Hi this is an assignment for my computer science lab. It is weird because if I compile and run with my c compiler from ubuntu gcc4.4, it works perfectly. But if I compile with the university's server (I connect with SSH) it messes up

The main purpose of the program is to change every first character of the name to uppercase

The textfile should contain this

ID FIRSTNAME LASTNAME
10 efron berlian
20 jim smith
30 what ever

the program will change the file to

ID FIRSTNAME LASTNAME
10 Efron Berlian
20 Jim Smith
30 What Ever

#include<stdio.h>
#include<ctype.h>

int main()
{
	char buffer[256];			//just a temp variable to store input
	
	int intTemp;			//temporary integer to store input
	char charTemp1[40];		//temporary strings to store input
	char charTemp2[40];		//temporary strings to store input
	
	FILE *filePtr;
	fpos_t position;		//save the position of the file Pointer
	
	filePtr = fopen("employee.dat", "r+");				//open the file for reading and writing
	
	fgets(buffer, 256, filePtr);						//go through the first line doing nothing
	fgetpos(filePtr, &position);						//save the pointer at beginning of second line
	
	while(fgets(buffer, 256, filePtr) != NULL)
	{	
		//fix the file
		sscanf(buffer, "%d %s %s", &intTemp, charTemp1, charTemp2);
		printf("before: %s %s\n", charTemp1, charTemp2);
		*charTemp1 = toupper(*charTemp1);
		*charTemp2 = toupper(*charTemp2);
		printf("after: %s %s\n", charTemp1, charTemp2);
		//print it back to the file
		fsetpos(filePtr, &position);						//set position to before the reading happens
		fprintf(filePtr, "%d\t%s\t%s\n", intTemp, charTemp1, charTemp2);		//print it back into the file
		
		fgetpos(filePtr, &position);						//save the pointer at the current position
	}
	
	fclose(filePtr);
	
	return 0;
}

can anyone tell me why? btw the server's gcc is 4.3

Thanks

Edit:

The output from my compiler:

efron@Caladbolg:~/Desktop/Lab7$ gcc fixcap.c
efron@Caladbolg:~/Desktop/Lab7$ ./a.out
before: efron berlian
after: Efron Berlian
before: jim smith
after: Jim Smith
before: what ever
after: What Ever
efron@Caladbolg:~/Desktop/Lab7$

The output from the server's compiler:

luna:~/60-141/Lab/Lab7>gcc fixcap.c
luna:~/60-141/Lab/Lab7>./a.out
before: efron berlian
after: Efron Berlian
before: efron berlian
after: Efron Berlian
before: jim smith
after: Jim Smith
before: Jim Smith
after: Jim Smith
luna:~/60-141/Lab/Lab7>gcc --version
gcc (GCC) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
luna:~/60-141/Lab/Lab7>

Edited 5 Years Ago by efronefron: n/a

Are you sure you working on identical data files?

The file would be in the same form

ID FIRSTNAME LASTNAME
10 efron berlian
20 jim smith
30 What Ever

the first line is just trash really and the rest is always number |space| string |space| string

And Yes I am sure Im using the same file

It should contain the same files, because I copied the whole folder

Edited 5 Years Ago by efronefron: n/a

The file would be in the same form

ID FIRSTNAME LASTNAME
10 efron berlian
20 jim smith
30 What Ever

the first line is just trash really and the rest is always number |space| string |space| string

Did you open the data files in nano or vim to verify the contents of the files are the same? I ask because the program seems to work in both cases and maybe its a case of the data files are not the same.

Edited 5 Years Ago by gerard4143: n/a

ok I am sure that the output is the same! no problem there. The only problem is that the program process it differently with different oompilers

The file is an output of another program so I am sure it is 100 % the same.

And btw it doesnt work at the server's compiler

look at it,
efron berlian
Efron Berlian
jim smith
Jim Smith
Jim Smith
Jim Smith

the last three lines are the same

Edited 5 Years Ago by efronefron: n/a

Try this version which is mostly like yours..This works on my system.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main()
{
  char buffer[256];
  char charTemp1[40];
  char charTemp2[40];
  int intTemp;
  fpos_t position;
  
  FILE *fd = NULL;
  
  if (!(fd = fopen("employee.dat", "r+")))
  {
    fputs("Could not open file!\n", stderr);
    exit(EXIT_FAILURE);
  }
  
  fgetpos(fd, &position);
  
  while (fgets(buffer, 256, fd) != NULL)
  {
    sscanf(buffer, "%d %s %s", &intTemp, charTemp1, charTemp2);
    
    charTemp1[0] = toupper(charTemp1[0]);
    charTemp2[0] = toupper(charTemp2[0]);
    
    fprintf(stdout, "%d %s %s\n", intTemp, charTemp1, charTemp2);
    fsetpos(fd, &position);
    fprintf(fd, "%d %s %s\n", intTemp, charTemp1, charTemp2);
    fgetpos(fd, &position);
  }
  
  fclose(fd);
  return 0;
}

Edited 5 Years Ago by gerard4143: n/a

Add fflush() right after fprintf(). Quoting man fsetpos:
The fsetpos() function shall fail if, either the stream is
unbuffered or the stream's buffer needed to be flushed, and the call to
fsetpos() causes an underlying lseek() or write() to be invoked

@ Gerard:
urs is exactly the same as mine. the only difference is that you change all the my pointers to []. anyway it doesnt work

@nezachhem:
Wow, can u explain more in depth I dont get what ur saying, but I tried to flush the filePtr anyway. And it WORKSSSS

and how come I dont need to flush in my ubuntu system, but need to flush it in the university's server?

@ Gerard:
urs is exactly the same as mine. the only difference is that you change all the my pointers to []. anyway it doesnt work

@nezachhem:
Wow, can u explain more in depth I dont get what ur saying, but I tried to flush the filePtr anyway. And it WORKSSSS

and how come I dont need to flush in my ubuntu system, but need to flush it in the university's server?

It probably has to do with the SSH connection...You should be doing it on your Ubuntu system as well.

Edited 5 Years Ago by gerard4143: n/a

First, the formal answer. Quoting the Standard,
output shall not be directly followed by input without an
intervening call to the fflush function or to a file positioning
function (fseek, fsetpos, or rewind), and input shall not be directly
followed by output without an intervening call to a file positioning
function

Your program satisfy the first requirement - you have fsetpos() between fgets() and fwrite(), but violates the second one - there's nothing between fprintf() and the next fgets() (note that fgetpos() is not a file positioning function).

Such a violation causes an undefined behaviour, which means that the program may occasionally work as expected, but not required to. The exact reason why did it work is unclear; I may only speculate that it has something to do with the underlying buffer sizes: your home system and the university server are configured differently.

The guts of the problem are with the IO buffering. I am afraid I can't explain "in depth" and stay in the format of a forum post.

In my system, which is ubuntu, fflush doesnt do anything. Ive tried using fflush(stdin) and it doesnt really flush anything, the characters in stdin are still there. fflush doesnt do anything in my system,its just like another empty line.

so should I still put it? just to make it universal?

And thank you very much for your time explaining about how this works.

In my system, which is ubuntu, fflush doesnt do anything. Ive tried using fflush(stdin) and it doesnt really flush anything, the characters in stdin are still there. fflush doesnt do anything in my system,its just like another empty line.

That's because the standard states fflush() is only required to work on output streams. It's not 'defined' for input streams, sayeth the standard. That doesn't mean a compiler can't implement fflush(stdin) , you just can't rely on it. And because of that, you shouldn't use it even if it IS defined. When you get used to using it on Windows, then you get to Ubuntu, suddenly nothing works.

This question has already been answered. Start a new discussion instead.