10 Replies - 681 Views - Last Post: 08 September 2010 - 02:38 AM Rate Topic: -----

#1 TimboTheChamp  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-October 09

Reading in values from a file in C

Posted 08 September 2010 - 12:38 AM

Hi there,

I'm having some trouble reading in values from a text file in C.

The file is of format:
1 1
2 1
2 1
3 2
..and so on. Also these values can go all the way up to 50

So far for that function I have:
static int processMoves(char filename[])
{
	//	LOCAL DECLARATIONS
	FILE	*moves;

	//	ATTEMPT TO OPEN THE FILE WITH READ ACCESS
	moves = fopen(filename, "r");

	//	CHECK IF ANYTHING WENT WRONG
	if(moves == NULL)
	{
		printf("Cannot open the moves file, '%s'.\n", filename);
		exit(EXIT_FAILURE);
	}

	//	rows HOLDS A ROW VALUE
	char rows;

	//	cols HOLDS A COLUMN VALUE
	char cols;

	//	processed COUNTS THE NUMBER OF MOVES PROCESSED
	int processed = 0;

	while(!feof(moves))
	{		
		//	SCAN THE FILE FOR ROW AND COLUMN VALUES
		scanf("%c%c", &rows, &cols);
		
	
		//	CHECK THAT THE ROW AND COLUMN VALUES ARE VALID
		//	SINCE THE ROTATE CELL FUNCTION CHECKS THE LOCATION
		//	IS WITHIN THE BOUNDS OF THE BOARD, WE DONT NEED TO
		//	CHECK IT HERE
		if(isValidMovesEntry(rows) && isValidMovesEntry(cols))
		{
			//	INITIALISE THE ROW AND COLUMN INPUTS AS A LOCATION TYPE
			LOCATION loc;
			loc.row = atoi(rows);
			loc.col = atoi(cols);

			//	IF THE INPUT IS VALID PERFORM THE MOVE
			rotateCell(loc);
		}
		else
		{
			//	IF THE INPUT IS INVALID PRINT AN ERROR MESSAGE
			//	AND HALT EXECUTION
			printf("The input in the moves file is invalid, either '%c' or '%c' is invalid.\n nRows = %d, nCols = %d\n", rows, cols, board.nRows, board.nCols);
		}

		processed++;
	}

	//	CLOSE THE FILE
	fclose(moves);

	return processed;
}



Just some additional information:
the isValidMovesEntry() function just returns true if the given character is a digit and false otherwise.
the output i keep getting is that the value for rows=1 but the value for columns comes out as 11.

Thanks for your time.

Is This A Good Question/Topic? 0
  • +

Replies To: Reading in values from a file in C

#2 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Reading in values from a file in C

Posted 08 September 2010 - 01:05 AM

scanf("%c%c", &rows, &cols);
Tell me, does scanf() try to read from file, or does it expect you to enter two characters? I tell you, that scanf() expects input from console. You can use fscanf(), but still, I always go with a pair of fgets() and sscanf() after:
// more code above
char line[256];
while (fgets(line, 256, moves))
{		
   sscanf(line, "%c %c", &rows, &cols);	

   // do whatever you need with rows and cols
   // more code below
}


This also offers protection against unwanted buffer overflows.
EDIT: could you compile this? Because this is definitely wrong:
loc.row = atoi(rows);
loc.col = atoi(cols);


as atoi() expects a pointer to char, then you'd have to pass "rows" and "cols" by their address:
loc.row = atoi(&rows);
loc.col = atoi(&cols);


This post has been edited by sarmanu: 08 September 2010 - 01:08 AM

Was This Post Helpful? 1
  • +
  • -

#3 moopet  Icon User is offline

  • binary decision maker
  • member icon

Reputation: 339
  • View blog
  • Posts: 1,185
  • Joined: 02-April 09

Re: Reading in values from a file in C

Posted 08 September 2010 - 01:13 AM

I can see a couple of problems:
First, scanf reads from stdin, and you are reading from a file. You should be using fscanf instead. Second, you probably want to include the whitespace in your format string. At the moment, rows would equal '1' and cols would equal ' '.

Might be other issues, haven't tried it.

This post has been edited by moopet: 08 September 2010 - 01:14 AM

Was This Post Helpful? 0
  • +
  • -

#4 TimboTheChamp  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-October 09

Re: Reading in values from a file in C

Posted 08 September 2010 - 01:17 AM

Thanks for the replies

Yeh i realised the problem with atoi after I posted. Sorry!

Now i get '11' and '111' as output?
Was This Post Helpful? 0
  • +
  • -

#5 moopet  Icon User is offline

  • binary decision maker
  • member icon

Reputation: 339
  • View blog
  • Posts: 1,185
  • Joined: 02-April 09

Re: Reading in values from a file in C

Posted 08 September 2010 - 01:18 AM

View Postsarmanu, on 08 September 2010 - 07:05 AM, said:

// more code above
char line[256];
while (fgets(line, 256, moves))
{		
   sscanf(line, "%c %c", &rows, &cols);	

   // do whatever you need with rows and cols
   // more code below
}


I think this might lead to a bug, because if your input is over 256 ccharacters long then there is a condition where the row might be in one buffer block and the col in the next. Which will offset everything by one place swapping values around. You'd have to put a check in making sure each block started on a newline.

View Postsarmanu, on 08 September 2010 - 07:05 AM, said:

as atoi() expects a pointer to char, then you'd have to pass "rows" and "cols" by their address:
loc.row = atoi(&rows);
loc.col = atoi(&cols);


I'm pretty sure that would bomb because it the strings wouldn't be null-terminated.
Was This Post Helpful? 0
  • +
  • -

#6 TimboTheChamp  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-October 09

Re: Reading in values from a file in C

Posted 08 September 2010 - 01:19 AM

How would I use fscanf in this situation?
Was This Post Helpful? 0
  • +
  • -

#7 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Reading in values from a file in C

Posted 08 September 2010 - 01:23 AM

When a line is over 256 characters long, the while loop will simply stop. Nothing else will happen. And really, it is your job to use the correct file structure, based on code design. If you put lines with more than 256 characters (knowing that you shouldn't do that), then that's your own problem.

Quote

I'm pretty sure that would bomb because it the strings wouldn't be null-terminated.

Not sure what you mean by that. atoi() converts a string (or a char) to integer. rows and cols are chars, so we are not talking about any NULL terminations here.

@op: http://www.crasseux....ial/fscanf.html

This post has been edited by sarmanu: 08 September 2010 - 01:30 AM

Was This Post Helpful? 0
  • +
  • -

#8 TimboTheChamp  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-October 09

Re: Reading in values from a file in C

Posted 08 September 2010 - 01:43 AM

Okay, so I'm thinking fscanf() won't work because there isn't always going to be the same number of lines in the file. Would that be correct?

So currently for the input lines:
1 1
2 1
2 1
3 2
1 5

My output is:
11 and 111
22 and 122
22 and 122
33 and 233
11 and 511

Why, I do not know :whatsthat:
Was This Post Helpful? 0
  • +
  • -

#9 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Reading in values from a file in C

Posted 08 September 2010 - 01:46 AM

What did you do to get that output? Post the updated code.
Was This Post Helpful? 0
  • +
  • -

#10 TimboTheChamp  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 16
  • Joined: 11-October 09

Re: Reading in values from a file in C

Posted 08 September 2010 - 01:59 AM

I just put a printf right after I scanned the values in, just to make sure the problem wasnt elsewhere in my code.

        FILE	*moves;
	char 	line[BUFSIZ];

	while(fgets(line, sizeof line, moves))
	{		
		//	SCAN THE FILE FOR ROW AND COLUMN VALUES
		sscanf(line, "%c %c ", &rows, &cols);
		printf("Rows=%d, Cols=%d\n", atoi(&rows), atoi(&cols));


Was This Post Helpful? 0
  • +
  • -

#11 sarmanu  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 966
  • View blog
  • Posts: 2,362
  • Joined: 04-December 09

Re: Reading in values from a file in C

Posted 08 September 2010 - 02:38 AM

atoi() expects a C-string, not a char, so indeed it may provide wrong results. To convert the char to integer, simply subtract 48 ('0'). Try:
printf("Rows=%d, Cols=%d\n", rows - '0', cols - '0');


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1