我目前正在编写一个程序,它将读取文件/ proc / stat并解析每一行,作为标记存储,然后最终处理并在输出表中表示。我正处于能够让程序解析程序的阶段,但是当涉及以各种数组值存储令牌时,我收到错误:分段错误(核心转储)。由于我已经分配了内存,因此我不确定是什么导致这种情况。我也是C的初学者。
//standard input/output file to help with io operations
#include<stdio.h>
//standard library files to help with exit and other standard functions
#include<stdlib.h>
//header file for usleep function
#include <unistd.h>
#include <string.h> //header file for strtok function
int main()
{
//FILE pointer will need to be declared initially, in this example the name is fp
FILE *fp;
//A character pointer that will store each line within the file; you will need to parse this line to extract useful information
char *str = NULL;
//size_t defined within C is a unsigned integer; you may need this for getline(..) function from stdio.h to allocate buffer dynamically
size_t len = 0;
//ssize_t is used to represent the sizes of blocks that can be read or written in a single operation through getline(..). It is similar to size_t, but must be a signed type.
ssize_t read;
float cpu_line1[4];
float cpu_line2[4];
float cpu_line3[4];
float cpu_line4[4];
float cpu_line5[4];
float page[2];
float swap[2];
float intr;
float ctxt;
float btime;
//a variable declared to keep track of the number of times we read back the file
unsigned int sample_count = 0;
//opening the file in read mode; this file must be closed after you are done through fclose(..); note that explicit location of the file to ensure file can be found
fp = fopen("/proc/stat", "r");
//checking if the file opening was successful; if not we do not want to proceed further and exit with failure code right away
if(fp == NULL)
{
exit(EXIT_FAILURE);
}
int i = 0;
char **string = NULL; //declaration of string
string = (char**)malloc(10*sizeof(char*)); //assign space for 10 pointers to array
for (i=0; i<10; i++) //allocate 50 bytes to each string in the array
{
string[i] = (char*)malloc(50*sizeof(char));
}
char *s = NULL;
//a loop that will read one line in the file at a time; str will read the line; len will store the length of the file
while(1)
{
printf("\e[1;1H\e[2J"); //this line will make sure you have cleared the previous screen using C's powerful format specifiers
printf("----------------------------------------------------------------\n");//used for presentation
printf("Sample: %u\n", sample_count); //showing the sample count
int i = 0; //counter
while ((read = getline(&str, &len, fp)) != -1)
{
// printf("Retrieved line: \n%sof length: %zu, allocated buffer: %u :\n", str, read, (unsigned int) len);
s = strtok(str, " ");
printf("Test program: %s\n", s);
}
if (i=0)
{
sprintf(string[0], s);
cpu_line1[0] = atoi(strtok(NULL, " "));
cpu_line1[1] = atoi(strtok(NULL, " "));
cpu_line1[2] = atoi(strtok(NULL, " "));
cpu_line1[3] = atoi(strtok(NULL, " "));
}
if (i=1)
{
sprintf(string[1], s);
cpu_line2[0] = atoi(strtok(NULL, " "));
cpu_line2[1] = atoi(strtok(NULL, " "));
cpu_line2[2] = atoi(strtok(NULL, " "));
cpu_line2[3] = atoi(strtok(NULL, " "));
}
if (i=2)
{
sprintf(string[2], s);
cpu_line3[0] = atoi(strtok(NULL, " "));
cpu_line3[1] = atoi(strtok(NULL, " "));
cpu_line3[2] = atoi(strtok(NULL, " "));
cpu_line3[3] = atoi(strtok(NULL, " "));
}
if (i=3)
{
sprintf(string[3], s);
cpu_line4[0] = atoi(strtok(NULL, " "));
cpu_line4[1] = atoi(strtok(NULL, " "));
cpu_line4[2] = atoi(strtok(NULL, " "));
cpu_line4[3] = atoi(strtok(NULL, " "));
}
if (i=4)
{
sprintf(string[4], s);
cpu_line5[0] = atoi(strtok(NULL, " "));
cpu_line5[1] = atoi(strtok(NULL, " "));
cpu_line5[2] = atoi(strtok(NULL, " "));
cpu_line5[3] = atoi(strtok(NULL, " "));
}
if(i=5)
{
sprintf(string[5], s);
page[0] = atoi(strtok(NULL, " "));
page[1] = atoi(strtok(NULL, " "));
}
if(i=6)
{
sprintf(string[6], s);
swap[0] = atoi(strtok(NULL, " "));
swap[1] = atoi(strtok(NULL, " "));
}
if(i=7)
{
sprintf(string[7], s);
intr = atoi(strtok(NULL, " "));
}
if(i=8)
{
sprintf(string[8], s);
ctxt = atoi(strtok(NULL, " "));
}
if(i=9)
{
sprintf(string[9], s);
btime = atoi(strtok(NULL, " "));
}
printf("----------------------------------------------------------------\n"); //used for presentation
usleep(500000);//this will ensure time delay
rewind(fp);//rewind the file pointer to start reading from the beginning
sample_count++;//update the sample count
}
//Frees pointers to make program memory efficient
free(str);
for (i=0; i <10; i++)
{
free(string[i]);
}
//once you are done, you should also close all file pointers to make your program memory efficient
fclose(fp);
return 0;
}
EDIT 这是在Cygwin中运行时程序的样子
样本:0
测试程序:cpu
测试程序:cpu0
测试程序:cpu1
测试程序:cpu2
测试程序:cpu3
测试程序:页面
测试程序:交换
测试程序:intr
测试程序:ctxt
测试程序:btime
分段错误(核心转储)
答案 0 :(得分:3)
除其他外,您的条件不正确:
if (i = 1) {
// do something.
}
这会将值1
分配给i
,而不是与1
进行比较。尝试将条件设为i == 1
。
答案 1 :(得分:3)
不确定分段错误的原因但我可以告诉你,如果你写
if (i=0) //it means assign the value 0 to i and if the value would be different from zero, follow the "then" branch
if (i==0) //is compare i to 0 and if true follow the "then" branch
所以如果有错误的话。
希望这会有所帮助:)
答案 2 :(得分:1)
如其他答案中所述,您应将if(i=0)
替换为if(i==0)
。
你得到分段错误,因为strtok()返回NULL,因此atoi()获取NULL作为参数:
cpu_line1[0] = atoi(strtok(NULL, " "));
cpu_line1[1] = atoi(strtok(NULL, " "));
cpu_line1[2] = atoi(strtok(NULL, " "));
cpu_line1[3] = atoi(strtok(NULL, " "));
只要有足够的令牌进行解析,此代码就可以正常运行。但是看起来你似乎经常试图获得下一个令牌。
在将它提供给atoi()之前,你应该检查strtok()的返回值是否为NULL。我建议使用循环来简化代码,并对每次使用atoi()时应用NULL检查。
这是一个简单的检查示例:
char* token = strtok(NULL, " ");
if(token != NULL)
cpu_line1[0] = atoi(token);
如果您将检查添加到每个strtok()调用中,这应该可以解决您的分段错误问题。