简体   繁体   English

使用 fscanf 时 C 中的分段错误(核心转储)

[英]Segmentation fault (Core dumped) in C while using fscanf

I'm working in C and gettting segmentation fault (core dumped).我在 C 中工作,并且得到了分段错误(核心已转储)。 The code compiles fine.代码编译得很好。 inputfile is the output of the top command, and I only want to return the rows by the root user. inputfile 是 top 命令的输出,我只想返回 root 用户的行。


#include <stdio.h>
#include <stdlib.h>
void main(){
FILE* file = fopen("C:/Users/danie/OneDrive/Desktop/inputfile.txt", "r");
if (file == NULL){
        printf("Error opening file");
}
char* user[10];
char* ptr[10];
char* ptr1[10];
char* ptr2[10];
char* ptr3[10];
char* ptr4[10];
char* ptr5[10];
char* ptr6[10];
char* ptr7[10];
char* ptr8[10];
char* ptr9[10];
char* ptr10[10];
while (fscanf(file, "%s %s %s %s %s %s %s %s %s %s %s %s", ptr, user, ptr1, ptr2,ptr3, ptr4, ptr5, ptr6, ptr7, ptr8, ptr9,ptr10)==1){
        if (strcmp(user,"root")==1)
printf("%s %s %s %s %s %s %s %s %s %s %s %s\n", ptr, user, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6, ptr7, ptr8, ptr9, ptr10);

}
}

Edit: Thank you all for your help!编辑:谢谢大家的帮助! I'm super new to C. Clearly I had a lot of misunderstandings.我对 C 非常陌生。显然我有很多误解。 I no longer receive the segmentation fault, but my output file is a bunch of nonsense.我不再收到分段错误,但我的输出文件是一堆废话。 https://imgur.com/a/XjdYZXY https://imgur.com/a/XjdYZXY

A segmentation fault is a memory access error.分段错误是内存访问错误。 Replace all the char* name_of_array[10];替换所有的char* name_of_array[10]; into char name_of_array[10];进入char name_of_array[10]; as arrays are pointers themselves.因为数组本身就是指针。 This char* name_of_array[10];这个char* name_of_array[10]; is an array of pointers.是一个指针数组。

Then I see another error: according to the documentation , fscanf returns the number of items successfully filled.然后我看到另一个错误:根据文档fscanf返回成功填充的项目数。 So instead of if(fscanf(file, ...) == 1) write if(fscanf(file, ...) != 0) (or better if(fscanf(file, ...)) ).所以,而不是if(fscanf(file, ...) == 1)if(fscanf(file, ...) != 0) (或者更好的if(fscanf(file, ...)) )。

A similar error appears in if(strcmp(user, "root") == 1) : it should be if(strcmp(user, "root") == 0) ( documentation ).类似的错误出现在if(strcmp(user, "root") == 1) :它应该是if(strcmp(user, "root") == 0)文档)。

I hope this helps you.我希望这可以帮助你。


EDIT: I managed to make it work, although it probably can be improved. 编辑:我设法让它工作,虽然它可能可以改进。

 #include <stdio.h> #include <string.h> int main() { char pid[10]; char user[10]; char pr[10]; char ni[10]; char virt[10]; char res[10]; char shr[10]; char s[10]; char cpu[10]; char mem[10]; char time[10]; char command[10]; FILE* file = fopen("C:/Users/danie/OneDrive/Desktop/inputfile.txt", "r"); if (file == NULL) { printf("Error opening file"); } char line[150]; while (fgets(line, 150, file) != NULL) { sscanf(line, "%s %s %s %s %s %s %s %s %s %s %s %s", pid, user, pr, ni, virt, res, shr, s, cpu, mem, time, command); if(strcmp(user, "root") == 0) { printf("%s %s %s %s %s %s %s %s %s %s %s %s", pid, user, pr, ni, virt, res, shr, s, cpu, mem, time, command); } } return 0; }

The *ptrs[10] need to be just ptr[10] else you are allocating an array of pointers rather than an array of characters. *ptrs[10] 需要只是 ptr[10] 否则您将分配一个指针数组而不是一个字符数组。

Not sure about the Windows top program but the linux one puts out a blank line at times.不确定 Windows 顶级程序,但 linux 有时会放出一个空行。 I consider it a bad idea to have scanf() a file in a while() loop.我认为在 while() 循环中使用 scanf() 文件是一个坏主意。

char buffer[256];
while (fgets( buffer, sizeof(buffer), file ) ) { 
        if ( ! strstr( buffer, " root " ) ) 
                continue;

Now you can inspect input before processing it.现在您可以在处理之前检查输入。 This root test is in addition to the one looking at "user" to filter out any odd lines from top we know are not to be printed, including strangely formatted lines.这个根测试是除了查看“用户”以从顶部过滤掉我们知道不会被打印的任何奇数行的之外,包括奇怪格式的行。

Same idea to avoid using sscanf() return values within an if as I like to pop the field return count into a variable:避免在if 中使用 sscanf() 返回值的相同想法,因为我喜欢将字段返回计数弹出到变量中:

int slen = sscanf(buffer, "%s %s %s %s %s %s %s %s %s %s %s %s",
                ptr, user, ptr1, ptr2,ptr3, ptr4, ptr5, ptr6, ptr7, ptr8, ptr9,ptr10);
if ( slen >= 10 )

This defends against short lines without a user , say a blank line.这可以防止没有用户的短行,比如空行。

If you never print anything it may be because your top program is putting out a bunch of terminal control codes for colors, etc., before each line potentially messing up your fields.如果您从不打印任何内容,那可能是因为您的顶级程序在每一行可能会弄乱您的字段之前输出了一堆用于颜色等的终端控制代码。 I had to had edit out of my data file to get the code to work.我不得不编辑我的数据文件才能使代码正常工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM