Использовать strcpy () или strncpy () для массива строк? - PullRequest
0 голосов
/ 20 марта 2020

Я пытаюсь скопировать строку в массиве с заданным индексом в другой массив строк, какие-либо предложения? При попытке распечатать значение tempVal для любого заданного индекса ничего не возвращается.

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

int main(void) {

   const int NUM_VALS = 20;
   int i;
   int matchCount = 0;

   int actualInput;
   scanf("%d", &actualInput);
   char userString[actualInput][NUM_VALS];
   char tempVal[actualInput][NUM_VALS];

   for (i = 0; i < actualInput; ++i) {
      scanf("%s", userString[i]);
      // printf("%s", userString[i]);
         strncpy(userString[i], tempVal[i], strlen(userString[i])); // < -- Not sure how to make work
         printf("%s", tempVal[i]); // <-- Doesn't output anything?
   }

   return 0;
}

Ответы [ 3 ]

0 голосов
/ 20 марта 2020

Неудивительно, почему вы не получили соответствующий вывод, потому что с предоставленным кодом вы, вероятно, получите ошибку сегментации. Помимо этого, в коде есть несколько проблем. Чтобы объяснить их все, а также ответить на главный вопрос, взорвется рамка. Вы можете увидеть, как я исправил код следующим образом.

char * strcpy (char * destination, const char * source)

strcpy является потенциальным риск переполнения буфера, если буфер destination char недостаточно велик для хранения строки, которая будет скопирована source. Это в вашем случае хорошо, потому что все буферы userString[i] и tempVal[i] имеют одинаковую емкость (количество элементов char), но при изменении кода это может быть вредно.

Обратите внимание, что вы Также следует ограничить количество вводимых символов, когда вы ловите строку из stdin. По этой причине fgets() безопаснее, чем scanf(), поскольку для него явно требуется максимальное количество символов для чтения.

char * strncpy (char * destination, const char * source, size_t num );

strncpy не может добавить завершающий нулевой символ, если первые num символы исходной строки не содержат завершающего \0.

Скорее используйте snprintf(), который безопасен для 1. проверки размера буфера назначения и ограничения количества символов для чтения и 2. всегда добавляет нулевой символ (при условии, что процесс сканирования прошел успешно и ошибок нет) произошло):

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

int main(void) {

   const int NUM_VALS = 20;
   int i;

   int s_num;
   printf("Enter number of strings in array: ");
   scanf("%d", &s_num);
   getchar();

   char userString[s_num][NUM_VALS];
   char tempVal[s_num][NUM_VALS];

   for (i = 0; i < s_num; ++i) {
   printf("Enter string at userString[%d]: ",i);

   if(fgets(userString[i],NUM_VALS, stdin) == NULL)
   {
       // error handling
       if(ferror(stdin))
       {
            // handle I/O error.
       }
       else if(feof(stdin))
       {
           // end of file is reached.
       }
   }
   else
       userString[i][strcspn(userString[i], "\n")] = 0;

   //printf("%s", userString[i]);
   }

   printf("\n");

   for (i = 0; i < s_num; ++i) {

      if(snprintf(tempVal[i], sizeof(tempVal[i]), "%s", userString[i]) < 0)
      {
        // error handling
        fprintf(stderr,"Encoding error occurred!");
      }
      printf("tempValue[%d]: %s\n", i, tempVal[i]);
   }
   return 0;
}

Вывод при пробном запуске:

Enter number of strings in array: 3               
Enter string at userString[0]: hello    
Enter string at userString[1]: world 
Enter string at userString[2]: test

tempValue[0]: hello
tempValue[1]: world
tempValue[2]: test
0 голосов
/ 21 марта 2020

Извините, ребята,

Я беру класс и плохо знаком с C. Я смог выяснить, как решить мою проблему. Я ценю предложения по исправлению кода, к сожалению, они выходят за рамки того, что я изучил в моем вводном курсе. Я должен был найти частоты слов, используя строковый массив и для циклов. Вот полный рабочий код:

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

int main(void) {

   const int NUM_VALS = 20;
   int i;
   int j;
   int matchCount = 0;

   int actualInput;
   scanf("%d", &actualInput);

   char userString[actualInput][NUM_VALS];
   char tempVal[actualInput][NUM_VALS];

   for (i = 0; i < actualInput; ++i) {
      scanf("%s", userString[i]);
      strcpy(tempVal[i], userString[i]);
     // printf("%s\n", userString[i]);
     // printf("%s\n", tempVal[i]);
   }

   for (i = 0; i < actualInput; ++i) {
      matchCount = 0;
      for (j = 0; j < actualInput; ++j) {
         if (strcmp(userString[i], tempVal[j]) == 0) {
            matchCount++;
         }
      }
      printf("%s %d\n", userString[i], matchCount);
   }



   return 0;
}
0 голосов
/ 20 марта 2020

используйте функцию, которая будет ограничивать число прочитанных символов и также ставит терминаты на ноль

for (int i = 0; i < actualInput; ++i) {
    fgets(userString[i], NUM_VALS, stdin);
    strcpy(tempVal[i], userString[i]); // < -- Not sure how to make work
    printf("%s\n", tempVal[i]); // <-- Doesn't output anything?
}
...