在 fread/fwrite 循环中出现分段错误,正在复制文件
Getting segmentation fault in fread/fwrite loop, copying file
我要将文件从输入的源复制到输入的目标。输入目的地后约 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] == '[=11=]') { 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] == '[=11=]') { 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] == '[=11=]')
return;
if(string[i] == '\n')
{
string[i] == '[=11=]';
return;
}
}
}*/
void remove_last_newline(char *str) {
if (*str == '[=11=]') return; /* do nothing if the string is empty */
while(str[1] != '[=11=]') str++; /* search for the end of the string */
if (*str == '\n') *str = '[=11=]'; /* if the last character is newline, delete it */
}
fgets
将读入的换行符存入缓冲区
它可能会阻止 fopen
打开 "the specified file" 并且 fopen
可能 return NULL
.
请删除缓冲区中的换行符。
这可以使用这个函数来完成:
void remove_last_newline(char *str) {
if (*str == '[=10=]') return; /* do nothing if the string is empty */
while(str[1] != '[=10=]') str++; /* search for the end of the string */
if (*str == '\n') *str = '[=10=]'; /* if the last character is newline, delete it */
}
请在读取文件名后将 source
和 destination
传递给此函数。
检查 fopen
的 return 值。
该程序在 fread(a, 1, 1, sp);
处出现 SEGFAULT
当 SP 为 NULL 时会发生这种情况。由于程序试图只读取一个字节,因此不会有任何溢出的机会。
fopen
失败,因为源代码末尾包含换行符。如果您在调用 fopen 之前从源和目标中删除 newline
字符,您的程序将正常运行。
主要问题是在文件名中留下 '\n'
然后下面的 fopen()
失败,代码没有检查 fopen()
return 值。其他 2 个答案回答得很好,至少 1 个值得接受。
随后的 OP 编辑将 int a[1]
更改为 int *a
,导致出现新错误。建议改为
char a[1];
我要将文件从输入的源复制到输入的目标。输入目的地后约 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] == '[=11=]') { 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] == '[=11=]') { 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] == '[=11=]')
return;
if(string[i] == '\n')
{
string[i] == '[=11=]';
return;
}
}
}*/
void remove_last_newline(char *str) {
if (*str == '[=11=]') return; /* do nothing if the string is empty */
while(str[1] != '[=11=]') str++; /* search for the end of the string */
if (*str == '\n') *str = '[=11=]'; /* if the last character is newline, delete it */
}
fgets
将读入的换行符存入缓冲区
它可能会阻止 fopen
打开 "the specified file" 并且 fopen
可能 return NULL
.
请删除缓冲区中的换行符。
这可以使用这个函数来完成:
void remove_last_newline(char *str) {
if (*str == '[=10=]') return; /* do nothing if the string is empty */
while(str[1] != '[=10=]') str++; /* search for the end of the string */
if (*str == '\n') *str = '[=10=]'; /* if the last character is newline, delete it */
}
请在读取文件名后将 source
和 destination
传递给此函数。
检查 fopen
的 return 值。
该程序在 fread(a, 1, 1, sp);
处出现 SEGFAULT
当 SP 为 NULL 时会发生这种情况。由于程序试图只读取一个字节,因此不会有任何溢出的机会。
fopen
失败,因为源代码末尾包含换行符。如果您在调用 fopen 之前从源和目标中删除 newline
字符,您的程序将正常运行。
主要问题是在文件名中留下 '\n'
然后下面的 fopen()
失败,代码没有检查 fopen()
return 值。其他 2 个答案回答得很好,至少 1 个值得接受。
随后的 OP 编辑将 int a[1]
更改为 int *a
,导致出现新错误。建议改为
char a[1];