fwrite и strcat, усекающие строку и записывающие бессмысленные значения

#c #fwrite #strcat

#c #fwrite #strcat

Вопрос:

При вызове функции, показанной ниже, она записывает определенные части строки в текстовый файл. иногда это приводит к удалению символов, поэтому номер удара молнии будет отображаться как «номер удара молнии». Он никогда должным образом не отображал номер удара в виде символа, он всегда отображается как «номер удара молнии:». Я думаю, что проблема может быть в strcat, но я не могу точно понять почему, буду признателен за любую помощь.

 void recordLightningStrike( int strikeNumber, char fileName[], FILE *filePointer )
{
   time_t systemTime;
   struct tm *UTCTime;

   char numberOfStrikes[6];
   char strikeTime[24];
   char stringOne[25];
   char stringTwo[55];
   //char finalString[200];

   itoa( strikeNumber, numberOfStrikes, 10 );
   time( amp;systemTime );
   UTCTime = localtime( amp;systemTime );
   strcpy( strikeTime, asctime( UTCTime ) );
   strcpy( stringOne, "Lightning Strike Number: " );
   strcpy( stringTwo, "Lightning Strike Occurred at: " );
   strcat( stringOne, numberOfStrikes );
   strcat( stringTwo, strikeTime );
   //strcpy( finalString, stringOne );
   //strcat( finalString, stringTwo );
   printf( " %s %c ", stringOne, 'n' );
   FILE *openPointer = fopen( fileName, "a" );
   if( openPointer!=NULL )
   {
      fwrite( stringOne, sizeof(char), sizeof(stringOne), openPointer );
      fwrite( stringTwo, sizeof(char), sizeof(stringTwo), openPointer );
   }
   fclose( openPointer );  
}
  

Ответ №1:

Объявите оба буфера (stringOne и stringTwo) больше. И не используйте sizeof() но strlen . Также, для повышения производительности, записывайте каждый буфер одновременно, меняя местами аргументы size и count (фактически, вычисляя размер буфера и записывая 1 буфер):

 .
.
.
char stringOne[50]; // guess; you could compute it more tightly
char stringTwo[60]; // guess; you could compute it more tightly
.
.
.
fwrite( stringOne, sizeof(char) * strlen(stringOne), 1, openPointer );
fwrite( stringTwo, sizeof(char) * strlen(stringTwo), 1, openPointer );
.
.
.
  

Вышеуказанные настройки, вероятно, исправят вашу программу. Но вы могли бы упростить чтение, используя snprintf() для печати в буфер или, что еще лучше, fprintf() для печати непосредственно в FILE* :

 fprintf( openPointer, "Lightning Strike Number: %dn", strikeNumber );
fprintf( openPointer, "Lightning Strike Occurred at: %sn", asctime( UTCTime ) );
  

Комментарии:

1. Ваше предложение по использованию strlen устранило проблему с ненужными значениями, однако, даже когда я увеличил размер stringOne до 60, количество ударов по-прежнему не отображалось. Однако использование fprintf решило проблему, спасибо. Если у вас есть какое-либо представление о том, почему fwrite не сработал, это было бы оценено

Ответ №2:

strcat не изменит размер вашего массива символов, поэтому строка

 strcat( stringOne, numberOfStrikes );
  

массив переполняется, и число не сохраняется. Попробуйте увеличить размер stringOne на несколько слотов.

Ответ №3:

stringOne в нем недостаточно места. Исходная строка, которую вы копируете в нее ( "Lightning Strike Number: " ), уже переполняет буфер из 25 символов, поскольку строка состоит из 26 символов, включая завершающий нулевой символ. Тогда вам strcat еще больше понравится. Не делайте ваши размеры строк такими маленькими.