当前,我正在尝试创建一个C程序,该程序打印文本文件的最后几行,并通过命令行读取。但是,当我尝试将字符串从fgets复制到主数组时,当前正在导致分段错误。我无法解决此问题,因此无法测试其余代码。我将如何开始解决细分错误?我在下面发布了代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i=1,j,printNumber;
char **arr = (char **) malloc (100 * sizeof(char *));
char *line = (char *) malloc (80 * sizeof(char));
if (argc == 1) {
printNumber = 10;
}
else {
printNumber = atoi(argv[1]);
}
while (fgets(line,80,stdin) != NULL) {
if (line != NULL) {
line[strlen(line)-1] = '\0';
strcpy(arr[i],line); //SEGMENTATION ERROR!!!!
}
else {
free(line);
strcpy(arr[i],NULL);
}
i++;
printf("%d ",i);
}
free(arr);
for (j = i-printNumber-1; j < i-1; j++) {
printf("%s ", arr[j]);
}
printf("\n");
return 0;
}
答案 0 :(得分:2)
您正在为arr
分配空间,这是指向char
的指针的指针,但没有在char *
内分配任何单独的arr
指针。
由于您为arr
分配了100 * sizeof(char *)
的大小,因此我假设您要在arr
中有100个子条目。当然可以:
for(i = 0; i < 100; i++)
arr[i] = malloc(80 * sizeof(char));
然后,当您释放arr
时:
for(i = 0; i < 100; i++)
free(arr[i]);
free(arr);
请注意,始终检查malloc
是否失败(NULL
的返回值)并进行处理,并在释放一次指针后将其设置为NULL
以避免重复,这是一种好习惯的错误。
答案 1 :(得分:0)
您并不总是知道最长的行的长度(直到尝试阅读时才知道)或希望跟踪的最后几行(但在运行时给出)。因此,在分配内存或委托给您执行此操作的函数之前,必须先知道这两个值。
#include <stdio.h>
#include <stdlib.h>
struct Line {
char *line; // content
size_t storage_sz; // allocation size of line memory
ssize_t sz; // size of line, not including terminating null byte ('\0')
};
int main(int argc, char *argv[]) {
int max_lines = 10;
if (argc > 1) {
max_lines = atoi(argv[1]);
}
if (max_lines < 0) {
fprintf(stderr, "%s\n", "Sorry, no defined behaviour of negative values (yet)\n");
return EXIT_FAILURE;
}
// keep an extra slot for the last failed read at EOF
struct Line *lines = (struct Line *) calloc(max_lines + 1, sizeof(struct Line));
int end = 0;
int size = 0;
// only keep track of the last couple of lines
while ((lines[end].sz = getline(&lines[end].line, &lines[end].storage_sz, stdin)) != -1) {
end++;
if (end > max_lines) {
end = 0;
}
if (size < max_lines) {
size++;
}
}
// time to print them back
int first = end - size;
if (first < 0) {
first += size + 1;
}
for (int count = size; count; count--) {
// lines might contain null bytes we can't use printf("%s", lines[first].line);
fwrite(lines[first].line, lines[first].sz, 1u, stdout);
first++;
if (first > size) {
first = 0;
}
}
// clear up memory after use
for (int idx = 0; idx <= max_lines; idx++) {
free(lines[idx].line);
}
free(lines);
return EXIT_SUCCESS;
}