Написать программу, которая считывает строки и записывает их в файл

#c

#c

Вопрос:

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

Напишите программу, которая считывает строки и записывает их в файл. Строка должна быть динамически распределена, и строка может быть произвольной длины. Когда строка прочитана, она записывается в файл. Сначала должна быть записана длина строки, затем двоеточие (‘:’), а затем строка. Программа останавливается, когда пользователь вводит одну точку (‘.’) в строке.

Например:

Пользователь вводит: это тест

Программа записывает в файл: 14: это тест

Подсказка: fgets() записывает перевод строки в конец строки, если она вписывается в строку. Начните с небольшой длины, например 16 символов, если вы не видите перевод строки в конце, затем перераспределите строку, чтобы добавить больше места, и продолжайте добавлять новые данные в строку, пока не увидите перевод строки в конце. Тогда вы знаете, что прочитали всю строку. Затем удалите любые ‘ r’ или ‘n’ из строки и запишите длину строки и строку в файл. Освободите строку, прежде чем запрашивать новую строку.

МОЙ КОД:

 #pragma warning(disable: 4996)

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

#define MAX_NAME_SZ 256


int main()
{

    char key[] = ".n";
    char* text;

    text = (char*)malloc(MAX_NAME_SZ);
    if (text == NULL)
    {
        perror("problem with allocating memory with malloc for *text");
        return 1;
    }

    FILE* fp;
    fp = fopen("EX13.txt", "w");
    if (fp == NULL)
    {
        perror("EX13.txt not opened.n");
        return 1;
    }

    printf("Enter text or '.' to exit: ");
    while (fgets(text, MAX_NAME_SZ, stdin) amp;amp; strcmp(key, text))
    {
        fprintf(fp, "%ld: %s", strlen(text) - 1, text);
        printf("Enter text or '.' to exit: ");
    }

    free((void*)text);
    fclose(fp);

    puts("Exit program");

    return 0;
} 
  

КОНКРЕТНЫЙ ВОПРОС:

Как я могу заставить программу разрешать произвольно длинные строки, чтобы не было никаких ограничений на длину строки? Спасибо

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

1. Используйте std::getline with std::string . Существует бесчисленное множество примеров.

2. Это похоже на код C, а не C . Решения для разных языков будут разными, поэтому, если вы действительно ищете ответ на C, вы должны пометить его соответствующим образом.

3. Ну, если предполагается, что это C, то вот подсказка: прочитайте подсказку в вашем вопросе

4. Увидев подсказку в вашем вопросе, вам нужно будет спросить более конкретно, что заставило вас застрять. Сосредоточьтесь на конкретной проблеме, с которой вы столкнулись, пытаясь работать в соответствии с подсказкой вашего учителя.

5. @4386427 это именно его вопрос, заданный после кода.

Ответ №1:

Вы могли бы объявить указатель на char, читать char по char и продолжать использовать перераспределение указателя, пока не дойдете до ‘n’:

 int main()
{
   char key[] = "."; //Excluded the n since I'm not using fget
   char* text;

   FILE* fp;
   fp = fopen("EX13.txt", "w");
   if (fp == NULL)
   {
      perror("EX13.txt not opened.n");
      return 1;
   }

   printf("Enter text or '.' to exit: ");

   int cont = 0;
   while (1) //read all chars
   {
       if(!cont) //if it is the first, allocate space for 1
           text = (char*) malloc(sizeof (char));
       else //otherwise increase the space allocated by 1
           text = (char*) realloc(text, (cont   1) * sizeof(char));
     
       scanf("%c", amp;text[cont]); //read a single char
       if(text[cont] == 'n') //see if it is the end of line
       {
           text[cont] = 0; //if it is the end of line, then it is the end of the string
           if(!strcmp(key, text)) //if the string is just a dot, end the loop 
               break;
           fprintf(fp, "%ld: %sn", cont, text);
           printf("Enter text or '.' to exit: ");
           cont = 0; //restarting the counter for the next input
           free(text); // freeing after each iteration. you can optimize to maintain the space and only increase after getting to a bigger string than the previous you had so far
        }
        else //if it is not the end of the string, increase its size by 1
           cont  ;
   }

   free((void*)text);
   fclose(fp);

   puts("Exit program");

   return 0;
}
  

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

1. @vmp. Спасибо. Единственной ошибкой компилятора является «потенциально неинициализированная переменная локального указателя», текст «используется» в строке, где находится realloc . Какие-либо предложения, пожалуйста?

2. вероятно, это предупреждение, поскольку cont начинается с 0, он всегда будет вводить if первым.

Ответ №2:

Предлагаю использовать getline()

Похоже, это задание для класса, поэтому я не буду писать код для вас.

Примечание: чтобы getline() функция была видна в Linux, в начале вашего кода вам понадобится оператор, подобный:

 #define _GNU_SOURCE
  

или

 #define _POSIX_C_SOURCE 200809L
  

getline(3)

Имя

  getdelim, getline -- get a line from a stream
  

БИБЛИОТЕКА

  Standard C Library (libc, -lc)
  

КРАТКОЕ ОПИСАНИЕ

  #include <stdio.h>

 ssize_t
 getdelim(char ** restrict linep, size_t * restrict linecapp,
     int delimiter, FILE * restrict stream);

 ssize_t
 getline(char ** restrict linep, size_t * restrict linecapp,
     FILE * restrict stream);
  

Описание

  The getdelim() function reads a line from stream, delimited by the char-
 acter delimiter.  The getline() function is equivalent to getdelim() with
 the newline character as the delimiter.  The delimiter character is
 included as part of the line, unless the end of the file is reached.

 The caller may provide a pointer to a malloced buffer for the line in
 *linep, and the capacity of that buffer in *linecapp.  These functions
 expand the buffer as needed, as if via realloc().  If linep points to a
 NULL pointer, a new buffer will be allocated.  In either case, *linep and
 *linecapp will be updated accordingly.
  

ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ

  The getdelim() and getline() functions return the number of characters
 written, excluding the terminating NUL character.  The value -1 is
 returned if an error occurs, or if end-of-file is reached.
  

ПРИМЕРЫ

  The following code fragment reads lines from a file and writes them to
 standard output.  The fwrite() function is used in case the line contains
 embedded NUL characters.

       char *line = NULL;
       size_t linecap = 0;
       ssize_t linelen;
       while ((linelen = getline(amp;line, amp;linecap, fp)) > 0)
               fwrite(line, linelen, 1, stdout);
  

ОШИБКИ

  These functions may fail if:

 [EINVAL]           Either linep or linecapp is NULL.

 [EOVERFLOW]        No delimiter was found in the first SSIZE_MAX characters.

 These functions may also fail due to any of the errors specified for
 fgets() and malloc().
  

Примечание: вам нужно будет перейти к free() строке, когда код будет завершен, чтобы избежать утечки памяти.

Примечание: для удаления любого завершающего ‘ n’ вы можете использовать:

 line[ strcspn( line, "n" ) ] = '';
  

Примечание: после удаления любого завершающего ‘ n’ вы можете использовать:

 size_t length = strlen( line );
  

Чтобы получить длину строки в байтах.

Затем выведите эту длину и строку, используя:

 printf( "%zu:%s", length, line );