Получение ошибки сегментации в цикле fread/fwrite, копирование файла

Я должен скопировать файл из предполагаемого источника в предполагаемый пункт назначения. Я получаю ошибку ошибки сегментации примерно через 2 секунды после ввода пункта назначения. Выходной файл создан так fopen() работает.

Я посмотрел в Интернете, и я вижу много c=getc(fp), я предпочитаю fread() а также fwrite() на этот вопрос, потому что это немного более простой.

Код

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

//void rmnewline(char *string);
void remove_last_newline(char *str);

int main()
{
  char x[3];
  x[0]='y';
  int ch;

  while(x[0]=='y'||x[0]=='Y')
  {
    char source[256], destination[256];
    int *a;

    printf("Enter a source file: ");
    fgets(source, 256, stdin);
    if (source[254] == '\n' && source[255] == '\0') { while ( (ch = fgetc(stdin)) != EOF && ch != '\n'); }
    remove_last_newline(source);

    printf("Enter a destination file: ");
    fgets(destination, 256, stdin);
    if (destination[254] == '\n' && destination[255] == '\0') { while ( (ch = fgetc(stdin)) != EOF && ch != '\n'); }
    remove_last_newline(destination);

    FILE *sp, *dp;

    sp = fopen(source, "r");
    if (sp == NULL) { printf("ERROR: Could not open source file."); exit(1); }
    dp = fopen(destination, "w");
    if (dp == NULL) { printf("ERROR: Could not open destination file."); exit(1); }
    while(1)
    {
      fread(a, 1, 1, sp);
      if (feof(sp))
      break;
      fwrite(a, 1, 1, dp);
    }

    fclose(sp);
    fclose(dp);

    printf("Run Again?(y/n):");
    fgets(x, 2, stdin);
    while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
 }

}

/*void rmnewline(char *string)
{
    int i, l = strlen(string);

    for(i=0; i<=l; i++)
    {
      if(string[i] == '\0')
         return;
      if(string[i] == '\n')
     {
       string[i] == '\0';
       return;
     }
  }

}*/

void remove_last_newline(char *str) {
    if (*str == '\0') return; /* do nothing if the string is empty */
    while(str[1] != '\0') str++; /* search for the end of the string */
    if (*str == '\n') *str = '\0'; /* if the last character is newline, delete it */
}

3 ответа

Решение

fgets сохранить символ новой строки, прочитанный в буфере.

Это может помешать fopen открыть "указанный файл" и fopen может вернуться NULL,

Пожалуйста, удалите символы новой строки, если они находятся в буфере.
Это можно сделать с помощью этой функции:

void remove_last_newline(char *str) {
    if (*str == '\0') return; /* do nothing if the string is empty */
    while(str[1] != '\0') str++; /* search for the end of the string */
    if (*str == '\n') *str = '\0'; /* if the last character is newline, delete it */
}

пожалуйста, передайте source а также destination к этой функции после чтения им имен файлов.

Проверьте возвращаемое значение fopen,
Программа получает SEGFAULT на fread(a, 1, 1, sp);Это происходит, когда SP равен NULL. Поскольку программа пытается прочитать только один байт, переполнения не будет.

fopen терпит неудачу, потому что источник состоит из символа новой строки в конце. Если вы удалите newline символ из источника и назначения перед вызовом fopen ваша программа будет работать нормально.

Главная проблема покидает '\n' в имени файла, а затем следующее fopen() не удалось, код не проверен fopen() возвращаемое значение Другие 2 ответа хорошо ответили, что и по крайней мере 1 заслуживает принятия.

Последующее редактирование OP изменено int a[1] в int *a вызывая новую ошибку. Предложить изменение на

char a[1];
Другие вопросы по тегам