The text file I generate from an graph generator is similar to:
:0 0|- 1|82 2|72
:1 0|87 1|- 2|74
:2 0|86 1|53 2|-
These are supposed to represent node and the distance to them.
line 1 is :1 1|- 2|82 3|72
it is saying the distance from node 0 to node 0 (0|-) is - (infinity)
and from node 0 to node 1 (1|82) is 82
and from node 0 to node 2 (2|72) is 72
But I want to load the values into a 2d array.
the array above should be
Graph[0][0] = -
Graph[0][1] = 82
Graph[0][2] = 72
etc...
I'm just not sure how when I read in the txt file to catch the :0 & :1 & :2 then separate 1|5.
any help would be great!
Thanks!
One problem is those - characters. If you replace them with 0, then you can use something like the following code:
// Open the file like this:
// std::ifstream fin ("whatever.txt");
char dummy;
for (int i = 0; i < n; ++i)
{
int x, d;
fin >> dummy >> x; // read ":1", etc.
assert (dummy == '=');
assert (x == i + 1);
for (int j = 0; j < n; ++j)
{
fin >> x >> dummy >> d; // read "2|42", etc.
assert (dummy == '|');
assert (x == j + 1);
Graph[i][j] = d;
}
}
All those asserts are there to make sure the redundant data in the file are as they are supposed to be. And don't forget to replace all '-'s with '0's.
You can see what I'm doing there. I'm reading the integers normally, and reading a character when the ':' and '|' symbols are.
A plain C approach which you may re-write as C++ or just use as-is. After all, this doesn't look like C++ critical code.
Note the use of a maximum length for fgets (granted, a C++ string could work better here) and a #define for "infinity", since you cannot store this value in a sensible way. It assumes all of your distances are positive, and that your data is as you have shown (i.e., no surprises such as huge numbers > MAX_INT, or inconsistent spacing).
The usual C++ approach of cin does not work well here, and neither does fscanf, since in both cases you need to read one character, determine if it is an - and if it is not re-read itself and any digits following it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_DATA_LENGTH 120
#define DIST_INFINITY 0xFFFFFFFF
unsigned int Graph[10][3];
int main (void)
{
FILE *fp;
char input_string[MAX_DATA_LENGTH], *token_ptr;
int graph_counter = 0, i;
fp = fopen ("graph.txt", "rt");
if (!fp)
{
printf ("data not found\n");
return -1;
}
do
{
if (fgets (input_string, MAX_DATA_LENGTH, fp) == NULL)
break;
token_ptr = input_string;
for (i=0; i<3; i++)
{
token_ptr = strchr (token_ptr, '|');
if (!token_ptr || !token_ptr[1])
break;
token_ptr++;
if (*token_ptr == '-')
Graph[graph_counter][i] = DIST_INFINITY;
else
Graph[graph_counter][i] = strtoul (token_ptr, NULL, 10);
token_ptr++;
}
if (i < 3)
break;
graph_counter++;
} while (1);
for (i=0; i<graph_counter; i++)
printf ("Graph[%d] = %u %u %u\n", i, Graph[i][0], Graph[i][1], Graph[i][2]);
return 0;
}
Related
I am trying to solve such competitive programming problem:
Alex likes to laugh a lot. Laughter is a sequence of alternating letters "a" and "h". For example, "ahahaha", "hah" and "a" are laughter and "abacaba" and "hh" are not.
Alex speaks very quickly, so all his words merge into one big one. You need to find out how long he can laugh. You have a line - a recording of Alex's conversation. Determine the maximum length of laughter in this conversation.
Input file is called "laugh.in"
Output file is called "laugh.out"
Input data:
The first line of the input file contains a single integer N (1 < N ≤ 10^5) - the length of the string with Alex's conversation. The second line contains a string of small Latin letters of length N - recording Alex's conversation.
Output data:
Output one number - the longest laugh length in Alex's conversation
Here's some examples of how input/output data must look like.
Examples:
Input in laugh.in
5
ahaha
Output in laugh.out
5
Input in laugh.in
24
ahahrunawayahahsofasthah
Output in laugh.out
4
Input in laugh.in
10
ahahaahaha
Output in laugh.out
5
So, here is my code, that is supposed to solve given problem:
#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
freopen("laugh.in", "r", stdin);
freopen("laugh.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, i;
cin >> n;
char *s = new char[n + 1];
getchar();
for (i = 0; i < n; i += 1)
{
s[i] = getchar();
}
s[n] = '\0';
int max_length = 0;
int length = 0;
for (i = 0; i < n; i += 1)
{
length += !length && (s[i] == 'a' || s[i] == 'h');
if ((s[i] == 'a' && s[i + 1] == 'h') ||
(s[i] == 'h' && s[i + 1] == 'a'))
{
length += 1;
}
else
{
max_length = max(max_length, length);
length = 0;
}
}
cout << max(max_length, length) << endl;
delete[] s;
return 0;
}
It only passes 13 tests with other 33 resulting in "Wrong answer" verdict.
So why my code is not working? Please, give counter examples to it or explain error.
Any help would be highly appreciated.
First of all, do not write everything in main (learn to avoid it ASAP).
Secondly, the task doesn't say anything about opening files.
Avoid the use of new delete in modern C++; it is a bad practice to use it.
Here is pattern you can start over:
size_t laugh_length(const std::string& s)
{
...
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
size_t l;
cin >> l;
std::string s;
s.reserve(l);
cin >> s;
cout << laugh_length(s) << '\n';
}
After an extra comment form OP I see another bit problem with OP code:
ios::sync_with_stdio(false);
and then use of:
getchar();
which is cstdio API which synchronization has been disabled.
https://wandbox.org/permlink/PJzjc1joKQgmpbwa
vs https://wandbox.org/permlink/aH3OypI94CpgNuxd
I have got some doubts while solving - Name That Number.
It goes like this -
Among the large Wisconsin cattle ranchers, it is customary to brand cows with serial numbers to please the Accounting Department. The cowhands don't appreciate the advantage of this filing system, though, and wish to call the members of their herd by a pleasing name rather than saying, "C'mon, #4734, get along."
Help the poor cowhands out by writing a program that will translate the brand serial number of a cow into possible names uniquely associated with that serial number. Since the cowhands all have cellular saddle phones these days, use the standard Touch-Tone(R) telephone keypad mapping to get from numbers to letters (except for "Q" and "Z"):
2: A,B,C 5: J,K,L 8: T,U,V
3: D,E,F 6: M,N,O 9: W,X,Y
4: G,H,I 7: P,R,S
Acceptable names for cattle are provided to you in a file named "dict.txt", which contains a list of fewer than 5,000 acceptable cattle names (all letters capitalized). Take a cow's brand number and report which of all the possible words to which that number maps are in the given dictionary which is supplied as dict.txt in the grading environment (and is sorted into ascending order).
For instance, brand number 4734 produces all the following names:
GPDG GPDH GPDI GPEG GPEH GPEI GPFG GPFH GPFI GRDG GRDH GRDI
GREG GREH GREI GRFG GRFH GRFI GSDG GSDH GSDI GSEG GSEH GSEI
GSFG GSFH GSFI HPDG HPDH HPDI HPEG HPEH HPEI HPFG HPFH HPFI
HRDG HRDH HRDI HREG HREH HREI HRFG HRFH HRFI HSDG HSDH HSDI
HSEG HSEH HSEI HSFG HSFH HSFI IPDG IPDH IPDI IPEG IPEH IPEI
IPFG IPFH IPFI IRDG IRDH IRDI IREG IREH IREI IRFG IRFH IRFI
ISDG ISDH ISDI ISEG ISEH ISEI ISFG ISFH ISFI
As it happens, the only one of these 81 names that is in the list of valid names is "GREG".
Write a program that is given the brand number of a cow and prints all the valid names that can be generated from that brand number or ``NONE'' if there are no valid names. Serial numbers can be as many as a dozen digits long.
Here is what I tried to solve this problem. Just go through all the names in the list and check which is satisfying the constraints given.
int numForChar(char c){
if (c=='A'||c=='B'||c=='C') return 2;
else if(c=='D'||c=='E'||c=='F') return 3;
else if(c=='G'||c=='H'||c=='I') return 4;
else if(c=='J'||c=='K'||c=='L') return 5;
else if(c=='M'||c=='N'||c=='O') return 6;
else if(c=='P'||c=='R'||c=='S') return 7;
else if(c=='T'||c=='U'||c=='V') return 8;
else if(c=='W'||c=='X'||c=='Y') return 9;
else return 0;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
freopen("namenum.in","r",stdin);
freopen("namenum.out","w",stdout);
string S; cin >> S;
int len = S.length();
freopen("dict.txt","r",stdin);
string x;
while(cin >> x){
string currName = x;
if(currName.length() != S.length()) continue;
string newString = x;
for(int i=0;i<len;i++){
//now encode the name as a number according to the rules
int num = numForChar(currName[i]);
currName[i] = (char)num;
}
if(currName == S){
cout << newString << "\n";
}
}
return 0;
}
Unfortunately, when I submit it to the judge, for some reason, it says no output produced that is my program created an empty output file. What's possibly going wrong?
Any help would be much appreciated. Thank You.
UPDATE: I tried what Some Programmer Dude suggested by adding a statement else return 0; at the end of the numOfChar function in case of a different alphabet. Unfortunately, it didn't work.
So after looking further at the question and exploring the information for Name That Number. I realized that it is not a current contest, and just a practice challenge. Thus, I updated my answer and also giving you my version of a successful submission. Nonetheless, that is a spoiler and will be posted after why your code was not working.
First, you forgot a } after the declaration of your number function. Secondary, you did not implement anything to check whether if the input fail to yield a valid name. Third, when you use numForChar() on the character of currName, the function yielded an integer value. That is not a problem, the problem is that it is not the ASCII code but is a raw number. You then compare that against a character of the input string. Of which, is an ASCII's value of a digit. Thus, your code can't never find a match. To fix that you can just add 48 to the return value of the numForChar() function or xor the numForChar() return's value to 48.
You are on the right track with your method. But there is a few hints. If you are bored you can always skip to the spoiler. You don't need to use the numForChar() function to actually get a digit value from a character. You can just use a constant array. A constant array is faster than that many if loop.
For example, you know that A, B, C will yield two and A's ASCII code is 65, B's is 66, and C's equal to 67. For that 3, you can have an array of 3 indexes, 0, 1, 2 and all of them stores a 2. Thus, if you get B, you subtract B's ASCII code 65 will yield 1. That that is the index to get the value from.
For getting a number to a character you can have a matrix array of char instead. Skip the first 2 index, 0 and 1. Each first level index, contain 3 arrays of 3 characters that are appropriate to their position.
For dictionary comparing, it is right that we don't need to actually look at the word if the length are unequal. However, besides that, since their dictionary words are sorted, if the word's first letter is lower than the range of the input first letter, we can skip that. On the other hand, if words' first letter are now higher than the highest of the input first letter, there isn't a point in continue searching. Take note that my English for code commenting are almost always bad unless I extensively document it.
Your Code(fixed):
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int numForChar(char c){
if (c=='A'||c=='B'||c=='C') return 2;
else if(c=='D'||c=='E'||c=='F') return 3;
else if(c=='G'||c=='H'||c=='I') return 4;
else if(c=='J'||c=='K'||c=='L') return 5;
else if(c=='M'||c=='N'||c=='O') return 6;
else if(c=='P'||c=='R'||c=='S') return 7;
else if(c=='T'||c=='U'||c=='V') return 8;
else if(c=='W'||c=='X'||c=='Y') return 9;
else return 0;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
ifstream fin("namenum.in");
ifstream dict("dict.txt");
ofstream fout("namenum.out");
string S;
fin >> S;
int len = S.length();
bool match = false;
string x;
while(dict >> x){
string currName = x;
if(currName.length() != S.length()) continue;
string newString = x;
for(int i=0;i<len;i++){
//now encode the name as a number according to the rules
int num = numForChar(currName[i]) ^ 48;
currName[i] = (char)num;
}
if(currName == S){
fout << newString << "\n";
match = true;
}
}
if ( match == false ){
fout << "NONE" << endl;
}
return 0;
}
Spoiler Code(Improved):
#include <fstream>
#include <string>
using namespace std;
// A = 65
// 65 - 0 = 65
const char wToN[] = {
// A ,B ,C ,D ,E ,F ,G ,H ,I ,
'2','2','2','3','3','3','4','4','4',
// J ,K ,L ,M ,N ,O ,P ,Q ,R ,S
'5','5','5','6','6','6','7','7','7','7',
// T ,U ,V ,W ,X ,Y ,Z
'8','8','8','9','9','9','9'
};
// 2 = {A, B, C} = 2[0] = A, 2[1] = B, 2[2] C
const char nToW[10][3] = {
{}, // 0 skip
{}, // 1
{'A','B','C'},
{'D','E','F'},
{'G','H','I'},
{'J','K','L'},
{'M','N','O'},
{'P','R','S'},
{'T','U','V'},
{'W','X','Y'}
};
int main(){
ifstream fin("namenum.in");
ifstream dict("dict.txt");
ofstream fout("namenum.out");
string S;
fin >> S;
// Since this will not change
// make this a const to make it
// run faster.
const int len = S.length();
// lastlen is last Index of length
// We calculate this value here,
// So we do not have to calculate
// it for every loop.
const int lastLen = len - 1;
int i = 0;
unsigned char digits[len];
unsigned char firstLetter[3];
// If not match print None
bool match = false;
for ( ; i < len; i++ ){
// No need to check upper bound
// constrain did not call for check.
if ( S[i] < '2' ) {
fout << "NONE" << endl;
return 0;
}
}
const char digit1 = S[0] ^ 48;
// There are 3 set of first letter.
// We get them by converting digits[0]'s
// value using the nToW array.
firstLetter[0] = nToW[digit1][0];
firstLetter[1] = nToW[digit1][1];
firstLetter[2] = nToW[digit1][2];
string dictStr;
while(dict >> dictStr){
// For some reason, when keeping the i = 0 here
// it seem to work faster. That could be because of compiler xor.
i = 0;
// If it is higher than our range
// then there is no point contineuing.
if ( dictStr[0] > firstLetter[2] ) break;
// Skip if first character is lower
// than our range. or If they are not equal in length
if ( dictStr[0] < firstLetter[0] || dictStr.length() != len ) continue;
// If we are in the letter range
// we always check the second letter
// not the first, since we skip the first
i = 1;
for ( int j = 1; j < len; j++ ){
// We convert each letter in the word
// to the corresponding int value
// by subtracting the word ASCII value
// to 65 and use it again our wToN array.
// if it does not match the digits at
// this current position we end the loop.
if ( wToN[dictStr[i] - 65] != S[j] ) break;
// if we get here and there isn't an unmatch then it is a match.
if ( j == lastLen ) {
match = true;
fout << dictStr << endl;
break;
}
i++;
}
}
// No match print none.
if ( match == false ){
fout << "NONE" << endl;
}
return 0;
}
I suggest you use c++ file handling. Overwriting stdin and stdout doesn't seem appropriate.
Add these,
std::ifstream dict ("dict.txt");
std::ofstream fout ("namenum.out");
std::ifstream fin ("namenum.in");
Accordingly change,
cin >> S --to--> fin >> S;
cin >> x --to--> dict >> x
cout << newString --to--> fout << newString
For a C/C++ assignment, I need to take an input line, starting with the character 's', followed by UP TO 3 separate integers. My issue is that, without vectors, I don't know how to account for an unknown number of integers (1-20).
For example, a test input would look like:
s 1 12 20
It was suggested to me to use cin.getline and take the whole line as a string, but how would I know where each integer would lie in a character array because of the possibility of single or double digits, let alone the number of integers in said string?
Construct a std::istringstream from the contents of the line, then keep using operator>> into an int, until it fail()s, stuffing each integer into a std::vector (after using the operator>> initially, once, to take care of the leading character).
You can mimic vectors using dynamic memory allocation. Initially create an array of size 2, using int *a = new int[2];
When this array fills up, make a new array of double the size, copy the old array in the new one and reassign a to the new array. Keep doing this until you have met the requirement.
EDIT
So getting the numbers through the string stream, if the array fills up, you could do:
int changeArr(int *a, int size){
int *b = new int[size*2];
for(int i=0;i<size;i++){
b[i] = a[i];
}
a = b;
return size*2;
}
int getNos(istringstream ss){
int *a = new int[2];
int cap = 2, i=0, number;
while(ss){
if(i>=cap){
cap = changeArr(a, cap);
}
ss >> a[i];
i++;
}
}
I have skipped the part about the first character, but I guess you can handle that.
Without vectors, you have a couple of approaches. (1) read an entire line at a time and tokenize the line with strtok or strsep, or (2) use the standard features built into strtol to walk down the string separating values with the pointer and end-pointer parameters to the function.
Since you know the format, you can easily use either. Both 1 & 2 above do the same thing, you are just using the tools in strtol to both tokenize and convert to a number in a single step. Here is a short example for handling a string followed by an unknown number of digits on each line:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
enum { BASE = 10, MAXC = 512 };
long xstrtol (char *p, char **ep, int base);
int main (void) {
char buf[MAXC] = "";
while (fgets (buf, MAXC, stdin)) { /* for each line of input */
char *p, *ep; /* declare pointers */
p = buf; /* reset values */
errno = 0;
printf ("\n%s\n", p); /* print the original full buffer */
/* locate 1st digit in string */
for (; *p && (*p < '0' || '9' < *p); p++) {}
if (!*p) { /* validate digit found */
fprintf (stderr, "warning: no digits in '%s'\n", buf);
continue;
}
/* separate integer values */
while (errno == 0)
{ int idx = 0;
long val;
/* parse/convert each number in line into long value */
val = xstrtol (p, &ep, BASE);
if (val < INT_MIN || INT_MAX < val) { /* validate int value */
fprintf (stderr, "warning: value exceeds range of integer.\n");
continue;
}
printf (" int[%2d]: %d\n", idx++, (int) val); /* output int */
/* skip delimiters/move pointer to next digit */
while (*ep && *ep != '-' && (*ep < '0' || *ep > '9')) ep++;
if (*ep)
p = ep;
else
break;
}
}
return 0;
}
/** a simple strtol implementation with error checking.
* any failed conversion will cause program exit. Adjust
* response to failed conversion as required.
*/
long xstrtol (char *p, char **ep, int base)
{
errno = 0;
long val = strtol (p, ep, base);
/* Check for various possible errors */
if ((errno == ERANGE && (val == LONG_MIN || val == LONG_MAX)) ||
(errno != 0 && val == 0)) {
perror ("strtol");
exit (EXIT_FAILURE);
}
if (*ep == p) {
fprintf (stderr, "No digits were found\n");
exit (EXIT_FAILURE);
}
return val;
}
(the xstrtol function just moves the normal error checking to a function to unclutter the main body of the code)
Example Input
$ cat dat/varyint.txt
some string 1, 2, 3
another 4 5
one more string 6 7 8 9
finally 10
Example Use/Output
$ ./bin/strtolex <dat/varyint.txt
some string 1, 2, 3
int[ 0]: 1
int[ 1]: 2
int[ 2]: 3
another 4 5
int[ 0]: 4
int[ 1]: 5
one more string 6 7 8 9
int[ 0]: 6
int[ 1]: 7
int[ 2]: 8
int[ 3]: 9
finally 10
int[ 0]: 10
You can provide a bit of tidying up, but this method can be used to parse an unknown number of values reliably. Look it over and let me know if you have any questions.
Since vectors aren't allowed, you'll need to find out how many numbers are in the line before you can make an array to hold them.
I won't just give you the entire code, since this is homework, but I'll show you what I would do to solve your problem.
If your lines will always look like this: "s number" or "s number number" or "s number number number", then you can easily find the number of numbers in the line by counting the spaces!
There will be one space in any string with one number (between the s and that number), and one more space for each number that follows the first.
So let's count the spaces!
int countSpaces(string s) {
int count = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == ' ') {
count++;
}
}
return count;
}
Passing these strings:
string test1 = "s 123 4 99999";
string test2 = "s 1";
string test3 = "s 555 1337";
to the countSpaces function will give us:
3
1
2
And with that information, we can make an array with the correct size to hold each value!
EDIT
Now I realize that you're having trouble grabbing the numbers from the string.
What I would do, is use the above method to find the number of numbers in the line. Then, I would use the std::string.find() function to determine where, and if, any spaces are in the string.
So let's say we had the line: s 123 45 678
countSpaces would tell us we have 3 numbers.
Then we make an array to hold our three numbers. I would also cut off the s part so you don't have to worry about it anymore. Note that you can use std::stoi to turn a string into a number!
Now we can loop while find(' ') doesn't return -1.
In our loop, I would take the substring from 0 to the first space, like so:
num = std::stoi( myLine.substr(0, myLine.find(' ') )
Then you can cut off the part you just used:
myLine = myLine.substr( myLine.find(' ') );
This will grab a number off the front of your string, then chop off that number from the string, and repeat the process while there is still a space in the string.
EDIT:
If you aren't guaranteed to have one space between each number, then you can delete excess spaces before doing this method or you can do it during the countSpaces loop. At that point, it would make more sense to call the function countNums or such.
An example function to remove stretches of spaces and replace them with one space:
void removeExtraSpaces(string s) {
bool inSpaces = (s[0] == ' ');
for (int i = 1; i < s.size(); i++) {
if (s[i] == ' ') {
if(inSpaces) {
s.erase(i);
} else {
inSpaces = true;
}
} else if(inSpaces) {
inSpaces = false;
}
}
}
So I have a data file that looks something like this:
x + y + z
30 45 50
10 20 30
The only characters I needed was the operators, so '+' '+' I was able to use file.get() to successfully get those characters and put them in an array. Problem is I need to get the next line of numbers, and assign them to the values x , y z . I know I cant use .get() , I would have to use getline. Will i have to eliminate the file.get() and use getline instead for first part also?
I looked at some of the questions posted on here but none of them were quite like mines. Note I'm actually going to be using these values for another part of my program, just used cout to see if my values were being read correctly
Here's my previous code:
main(int argc, char *argv[])
{
int a=0;
int n;
fstream datafile;
char ch;
pid_t pid;
int a, b, c, result;
string line;
datafile.open("data1.txt");
if(datafile)
{
for(int i=0; i <9; i++)
{
datafile.get(ch);
if (ch == '*'||ch == '/'||ch == '+'||ch == '-')
{
operations[a] = ch;
cout<<operations[a];
a++;
}
}
}
else
cout<<"Error reading file";
}
So this is how I was getting the first line of the file in the beginning. It worked like I wanted it to, may have not been the nicest coding but it worked. Nevertheless I tried to get the rest of the file, this time using getline, but instead of getting the numbers I was getting a bunch of random gibberish/numbers. I know if I use getline, the first line cannot be in my loop. I know this is how I would get the numbers.
while(getline(datafile, line))
{
istringstream ss(line);
ss >> x >> y >> z;
cout<<x<<""<<y<<""<<z;
}
Would the following make sense for the first line, or am I missing something:
string input;
std::getline(datafile, input)
for (int i = 0; i < input.size(); i++)
if (input[i] == '+' || ...)
{
operations[a] = input[i];
a++;
}
If you don't want to use getline, you could simply read the entire file stream (note that the bool is a rather naive way to handle the problem, I'd recommend something more elegant in your actual code):
bool first = true;
string nums;
int lines = 0;
vector<vector<int>> numlines;
vector<int> topush;
while (!datafile.eof())
{
char ch = datafile.get()
if (ch == 12 && first) //I don't know if '\n' is valid, I'd assume it is but here's the sure bet
first = false;
else if (first && (ch == '+' || ...))
{
operator[a] = ch;
a++;
}
else if (!first && (ch >= '0' && ch <= '9'))
{
if (!(datafile.peek() >= '0' && datafile.peek() <= '0'))
{
numlines[lines].push_back(atoi(nums.c_str());
nums.clear();
if (datafile.peek() == 12)
{
numlines.push_back(topush);
lines++;
}
}
else
nums = nums + ch;
}
Honestly, I can't be sure the above will work exactly right, I'd recommend you just modify your code to use getline exclusively. You'll need to add #include to get atoi.
Add this to your code:
while(!datafile.eof()){
string s;
getline(datafile, s);
istringstream in(s);
string tmp;
while(in >> tmp){
int i = stoi(tmp)
//Do something with i....
}
}
I have written a code to read file below but its not working.
Input file:
2 1 16
16 0 0
1 1 1234
16 0 0
1 1 2345
code is:
std::ifstream input_file;
evl_wire wire;
int num_pins,width,cycles,no;
std::vector<int>IP;
while(input_file)
{
input_file >> num_pins;//num_pins=2
if (pins_.size() != num_pins) return false;
for (size_t i = 0; i < pins_.size(); ++i)
{
input_file >> width;//width=1 for 1=0 ,=16 for i=2
if (wire.width != width) return false;
pins_[i]->set_as_output();
}
for (size_t i = 1; i < file_name.size(); i=i+1)
input_file>>cycles;
input_file>>no;
pins_=IP;
}
where std::vector<pin *> pins_; is in gate class and void set_as_output(); is in pin class
2 represent no of pins,1 width of first pin and 16 width of second pin.
here from second line in file 16 is no of cycles pins must remain at 0 0,for next 1 cycle pins must be assigned 1 and 1234 as inputs.
Some parts of your code are almost certainly wrong. Other parts I'm less certain about -- they don't make much sense to me, but maybe I'm just missing something.
while(input_file)
This is almost always a mistake. It won't sense the end of the file until after an attempt at reading from the file has failed. In a typical case, your loop will execute one more iteration than intended. What you probably want is something like:
while (input_file >> num_pins)
This reads the data (or tries to, anyway) from the file, and exits the loop if that fails.
if (pins_.size() != num_pins) return false;
This is less clear. It's not at all clear why we'd read num_pins from the file if we already know what value it needs to be (and the same seems to be true with width vs. wire.width).
for (size_t i = 1; i < file_name.size(); i=i+1)
input_file>>cycles;
This strikes me as the most puzzling part of all. What does the size of the string holding the file name have to do with anything? This has be fairly baffled.
I don't fully understand your code, but I don't see you are opening the input file anywhere. I think it should be:
std::ifstream input_file;
evl_wire wire;
int num_pins,width,cycles,no;
std::vector<int>IP;
input_file.open("name of the file");
if(input_file.is_open())
{
while(input_file >> num_pins) //num_pins=2
{
if (pins_.size() != num_pins) return false;
for (size_t i = 0; i < pins_.size(); ++i)
{
input_file >> width;//width=1 for 1=0 ,=16 for i=2
if (wire.width != width) return false;
pins_[i]->set_as_output();
}
for (size_t i = 1; i < file_name.size(); i=i+1)
input_file>>cycles;
input_file>>no;
pins_=IP;
}
input_file.close();
}
The function I used:
bool input::validate_structural_semantics()
{
evl_wire wire;
std::ifstream input_file;std::string line;
int x[]={1000};
for (int line_no = 1; std::getline(input_file, line); ++line_no)
std::string s; int i=0;
std::istringstream iss;
do
{
std::string sub;
iss >> sub;
x[i]=atoi(sub.c_str());
i++;
}
while (iss);
if (pins_.size()!=x[0]) return false;
for (size_t i = 0; i < pins_.size(); ++i)
{
if (wire.width != x[i+1]) return false;
pins_[i]->set_as_input();
}
for(size_t i=4;i<1000;i++)
{
for(size_t j=0;j<pins_.size();j++)
pins_.assign(x[i-1],x[i+j]);
}
return true;
}
This implementation is using arrays but it didn't work,although there isn't any compling error.