Печать указателя символа в C - я получаю плохое форматирование - PullRequest
0 голосов
/ 26 сентября 2010

Я читаю строку из файла, содержащего имена людей, первая строка содержит имена мужчин, а вторая строка содержит имена женщин. Затем я хочу сохранить эти имена в двух массивах, один для мужчин, другой для женщин, однако, когда я печатаю их, я получаю странные вещи. Я не уверен, что неправильно читаю их или печатаю неправильно

    char line[100];      //holds line read
    char *item;         //item in a line
    char *item2;
    int participants = 5;   //number of people in the event

            char* maleNames[participants];
            char* femaleNames[participants];

            fgets(line, 255, file);
            int i;
            item = strtok(line, " ");
            for(i=0; i<participants; i++)
            {
                maleNames[i] = item;  
                item = strtok(NULL, " ");


               }

        //read female names now
        fgets(line, 1024, file);
        item2 = strtok(line, " ");
        for(i=0; i<participants; i++)
        {
            femaleNames[i] = item2;
            item2 = strtok(NULL, " ");
        }

Эти строки читаются

John Jeffrey Adam Mark Peter
Jenny Alice Sally Wendy Amanda

Однако, когда я распечатываю их так:

        for(i=0;i<participants;i++)
        {
            printf("%s %s\n", maleNames[i], femaleNames[i]);
        }

Я получаю нечто совершенно другое:

Jenny Jenny
 Alice
ally Sally
Wendy Wendy
 Amanda

Примечание: если я печатаю имена мужчин сразу после того, как они прочитаны, прежде чем читать женские имена, то они печатаются правильно

Ответы [ 3 ]

2 голосов
/ 26 сентября 2010

Прежде всего (и не связано): вы объявляете line равным char[100]; однако вы используете fgets(line, 1024, file) и fgets(line, 255, file) - это переполнения буфера, ожидающие выполнения.

Затем определите, что происходит, когда вы читаете токен. Например, я бы сделал:

for(i=0; i<participants; i++)
{
    maleNames[i] = item;
    printf("Token %d: %s", i, item);
    item = strtok(NULL, " ");
}

Это позволит вам узнать, есть ли у вас проблемы на входе или выходе. В качестве альтернативы, выполните цикл отладчика и посмотрите, что именно там происходит.

Кроме того, я считаю, что вам нужно скопировать возвращаемое значение strtok в другой массив символов. Посмотрите на strdup, чтобы скопировать ваши строки.

1 голос
/ 26 сентября 2010

Как уже упоминалось @lacqui, у вас были потенциальные переполнения буфера.Я изменил fgets, чтобы передать sizeof (line1) -1 вместо жестко закодированного значения.Таким образом, компилятор выяснит, какой размер передать ... даже если позже вы решите увеличить / уменьшить размер буфера.Минус 1 означает, что fgets не перезапишет нулевой терминатор в конце.Я также инициализирую буферы, используя memset.

Я также добавил еще один буфер строки, потому что strtok изменяет строку, заменяя указанные символы разделителя на ноль и возвращая указатель на позицию токена в этой строке... strtok не копирует.

Я изменил разделители, добавив \ r и \ n в дополнение к пробелам.

#include <stdio.h>
#include <string.h>

int main() {
   char line1[100];      //holds line read
   char line2[100];
   char *item;         //item in a line
   char *item2;
   const int participants = 5;   //number of people in the event

   char* maleNames[participants];
   char* femaleNames[participants];

   FILE* file = fopen("names.txt", "r");

   memset(line1, 0, sizeof(line1));
   fgets(line1, sizeof(line1)-1, file);

   int i;
   item = strtok(line1, " \r\n");
   for(i=0; i<participants; i++)
   {
      maleNames[i] = item;  
      item = strtok(NULL, " \r\n");
   }

   //read female names now
   memset(line2, 0, sizeof(line2));
   fgets(line2, sizeof(line2)-1, file);

   item2 = strtok(line2, " \r\n");
   for(i=0; i<participants; i++)
   {
      femaleNames[i] = item2;
      item2 = strtok(NULL, " \r\n");
   }

   for(i=0;i<participants;i++)
   {
      printf("%s %s\n", maleNames[i], femaleNames[i]);
   }

   return 1;
}
1 голос
/ 26 сентября 2010

Не обращая внимания на другие проблемы (такие как размер, 255 и 1024, вы переходите к fgets, когда ваш буфер имеет длину всего 100 символов), эта проблема, скорее всего, связана с тем, что вы используете тот же буфер, символьную строку [100], для обоих вызовов функции fgets (). Strtok возвращает указатель на символ в буфере строк , поэтому, когда вы сохраняете в «строке» женские имена, все эти указатели относительно строки, когда строка содержит мужские имена, сейчас недействительны. Попробуйте сохранить женскую линию в другом буфере, она должна работать.

РЕДАКТИРОВАТЬ: Извините, если "не обращая внимания ..." звучит обескураживающе. Ничего более далекого от моего намерения. Все делают ошибки каждый раз, особенно когда учатся. Я желаю вам удачи в процессе:)

...