tags:

views:

255

answers:

4

EDIT: complete code with main is here http://codepad.org/79aLzj2H

and once again this is were the weird behavious is happening

for (i = 0; i<tab_size; i++)
{
  //CORRECT OUTPUT
  printf("%s\n", tableau[i].capitale);
  printf("%s\n", tableau[i].pays);
  printf("%s\n", tableau[i].commentaire);
  //WRONG OUTPUT
  //printf("%s --- %s --- %s |\n", tableau[i].capitale, tableau[i].pays, tableau[i].commentaire);
}


I have an array of the following strcuture

struct T_info
{
    char capitale[255];
    char pays[255];
    char commentaire[255];
};

struct T_info *tableau;

This is how the array is populated

int advance(FILE *f)
{
  char c;

  c = getc(f);
  if(c == '\n')
    return 0;

  while(c != EOF && (c == ' ' || c == '\t'))
  {
    c = getc(f);
  }

  return fseek(f, -1, SEEK_CUR);

}

int get_word(FILE *f, char * buffer)
{
  char c;
  int count = 0;
  int space = 0;

  while((c = getc(f)) != EOF)
    {
      if (c == '\n')
      {
    buffer[count] = '\0';
    return -2;
      }

      if ((c == ' ' || c == '\t') && space < 1)
      {
    buffer[count] = c;
    count ++;
    space++;
      }
      else
      {
    if (c != ' ' && c != '\t')
    {
      buffer[count] = c;
      count ++;
      space = 0;
    }       
    else /* more than one space*/
    {
     advance(f);
     break;
    }
      }
    }

   buffer[count] = '\0';
   if(c == EOF)
     return -1;

   return count;
}

void fill_table(FILE *f,struct T_info *tab)
{
    int line = 0, column = 0;

    fseek(f, 0, SEEK_SET);

    char buffer[MAX_LINE];
    char c;
    int res;

    int i = 0;
    while((res = get_word(f, buffer)) != -999)
    {
      switch(column)
      {
        case 0:
        strcpy(tab[line].capitale, buffer); 
        column++;
          break;
        case 1:
          strcpy(tab[line].pays, buffer);
          column++;
          break;
        default:
          strcpy(tab[line].commentaire, buffer);    
          column++;
          break;
      }
      /*if I printf each one alone here, everything works ok*/
          //last word in line
      if (res == -2)
      {
        if (column == 2)
        {
          strcpy(tab[line].commentaire, " ");       
        }
//wrong output here
        printf("%s -- %s -- %s\n", tab[line].capitale, tab[line].pays, tab[line].commentaire);

        column = 0;
          line++;
          continue;
      }
      column = column % 3;

      if (column == 0)
      {
        line++;
      }

      /*EOF reached*/
      if(res == -1)
        return;

    }
    return ;
}

Edit :

trying this

    printf("%s -- ", tab[line].capitale);
    printf("%s --", tab[line].pays);
    printf("%s --\n", tab[line].commentaire);

gives me as result

 --  --abi  -- Emirats arabes unis

I expect to get

Abu Dhabi -- Emirats arabes unis --

Am I missing something?

+5  A: 

Does printf have side effects?

Well, it prints to the screen. That's a side effect. Other than that: no.

is printf changing its parameters

No

I get wrong resutts [...] what is going on?

If by wrong results you mean that the output does not appear when it should, this is probably just a line buffering issue (your second version does not print newline which may cause the output to not be flushed).

sepp2k
+1 for stating the obvious side effect :)
Frank Shearar
Isn't printing to the screen the main effect?
Bruce
strange definition of side effect
Juliano
@Juliano: not really. It isn't unusual to define "side effect" as reading anything other than parameters, and writing or modifying anything other than the return value. Operations free of side effects then have useful properties. See http://en.wikipedia.org/wiki/Side_effect_%28computer_science%29. But I don't think that's what the questioner means...
Steve Jessop
A: 

I tested your code, adding the missing parts (MAX_LINE constant, main function and a sample datafile with three columns separated by 2+ whitespace), and the code works as expected.

Perhaps the code you posted is still not complete (fill_table() looks for a -999 magic number from get_word(), but get_word() never returns that), your main function is missing, so we don't know if you are properly allocating memory, etc.

Unrelated but important: it is not recommended (and also not portable) to do relative movements with fseek in text files. You probably want to use ungetc instead in this case. If you really want to move the file pointer while reading a text stream, you should use fgetpos and fsetpos.

Your approach for getting help is very wrong. You assumed that printf had side effects without even understanding your code. The problem is clearly not in printf, but you held information unnecessarily. Your code is not complete. You should create a reduced testcase that compiles and displays your problem clearly, and include it in full in your question. Don't blame random library functions if you don't understand what is really wrong with your program. The problem can be anywhere.

Juliano
Dude be sure I understand my code pretty well, the printf is doing the problem! so I wonder is it's the system after all, here is wots going wrong`for (i = 0; i<tab_size; i++) { //CORRECT OUTPUT printf("%s\n", tableau[i].capitale); printf("%s", tableau[i].pays); printf("%s\n", tableau[i].commentaire); //WRONG OUTPUT //printf("%s --- %s --- %s |\n", tableau[i].capitale, tableau[i].pays, tableau[i].commentaire); }`
martani_net
try this... printf("%s\n %s %s /n", tableau[i].capitale, tableau[i].pays, tableau[i].commentaire);
CVS-2600Hertz
A: 

From your comments, i am assuming if you use these printf statements,

  printf("%s\n", tableau[i].capitale);
  printf("%s", tableau[i].pays);
  printf("%s\n", tableau[i].commentaire);

then everything works fine...

So try replacing your single printf statement with this. (Line no. 173 in http://codepad.org/79aLzj2H)

  printf("%s\n %s %s /n", tableau[i].capitale, tableau[i].pays, tableau[i].commentaire);
CVS-2600Hertz
Please stop signing all your posts, and type in complete words. And while I don't think it's against any rules, the bolded-header on your posts is unorthodox and will probably annoy a bunch of people. don't take what I say personally, just letting you know. I'd put a smiley face here, but I just woke up and I never smile in the morning.
GMan
My day is over. I had my 3'rd cup of coffee 14 hours ago and I'm now well into my second beer. So, here's the omitted smiley: `:)`. BTW, welcome to Stack Overflow.
Tim Post
Oh, yes, try to avoid 'pastebin' type sites, its better to just paste the relevant code (or snippets) directly in a question or answer.
Tim Post
+1  A: 

It's highly unlikely that printf is your problem. What is far, far more likely is that you're corrupting memory and your strange results from printf are just a symptom.

There are several places I see in your code which might result in reading or writing past the end of an array. It's hard to say which of them might be causing you problems without seeing your input, but here are a few that I noticed:

  1. get_lines_count won't count the last line if it doesn't end in a newline, but your other methods will process that line
  2. advance will skip over a newline if it is preceded by spaces, which will cause your column-based processing to get off, and could result in some of your strings being uninitialized
  3. get_word doesn't do any bounds checks on buffer

There may be others, those were just the ones that popped out at me.

Mike McNertney