C fscanf给我重复的行
我试图通过重定向“ps”命令的输出来显示每个进程的详细信息。我已将ps输出重定向到一个文件。我从中读取并使用fscanf显示Pid和命令。但我看到有些行被复制了,在某些情况下,PID的值为负值C fscanf给我重复的行,c,linux,pid,scanf,ps,C,Linux,Pid,Scanf,Ps,我试图通过重定向“ps”命令的输出来显示每个进程的详细信息。我已将ps输出重定向到一个文件。我从中读取并使用fscanf显示Pid和命令。但我看到有些行被复制了,在某些情况下,PID的值为负值 void TR69_DM_GetProcDetails(char *FileName, int32_t *ProcCount, struct ProcessInfo *ProcVar) { char CharBuf[BUF_SIZE] ; int32_t i = 0; int P
void TR69_DM_GetProcDetails(char *FileName, int32_t *ProcCount, struct ProcessInfo *ProcVar)
{
char CharBuf[BUF_SIZE] ;
int32_t i = 0;
int Pid;
char Cmd[100];
FILE *FileDesc;
FileDesc = fopen (FileName, "r");
printf("\nFile pointer %ld\n", ftell(FileDesc));
fscanf (FileDesc, "%[^\n]\n", CharBuf);
puts(CharBuf);
printf("\nFile pointer %ld\n", ftell(FileDesc));
while ( EOF != fscanf (FileDesc, "%*s %lu %*d %*d %*s %*s %*s %s", &Pid, Cmd))
{
printf("\n PID is %d and cmd is %s", Pid, Cmd);
// i++;
}
}
我得到了以下输出示例:
可能出了什么问题?返回分配的数量。根据EOF
进行检查是不够的,因为有些赋值可能已经完成,而其余的赋值则没有,这意味着后续代码将处理过时或未初始化的值。当格式意外时,以下循环将在第一行停止处理,并避免过时的值:
while ( 2 == fscanf (FileDesc, "%*s %lu %*d %*d %*s %*s %*s %s", &Pid, Cmd))
{
}
一种改进的解决方案是先读取一行,然后使用解析读取的行。这将允许您检测EOF
,并允许多次尝试使用不同格式解析该行:
char line[1024];
while (fgets(line, sizeof(line), stdin))
{
if (2 == sscanf (line, "%*s %lu %*d %*d %*s %*s %*s %s", &Pid, Cmd))
{
}
else if (2 == sscanf (line, "some-other-format", &Pid, Cmd))
{
}
else
{
fprintf(stderr, "Unable to parse '%s'\n", line);
}
}
此外,通过指定sscanf()
应写入Cmd
的最大字符数,防止潜在的缓冲区溢出。这应该小于Cmd
的大小,为终止的空字符留出空间。例如:
if (2 == sscanf(line, "%lu %255s", &Pid, Cmd))
返回分配的数量。根据EOF
进行检查是不够的,因为有些赋值可能已经完成,而其余的赋值则没有,这意味着后续代码将处理过时或未初始化的值。当格式意外时,以下循环将在第一行停止处理,并避免过时的值:
while ( 2 == fscanf (FileDesc, "%*s %lu %*d %*d %*s %*s %*s %s", &Pid, Cmd))
{
}
一种改进的解决方案是先读取一行,然后使用解析读取的行。这将允许您检测EOF
,并允许多次尝试使用不同格式解析该行:
char line[1024];
while (fgets(line, sizeof(line), stdin))
{
if (2 == sscanf (line, "%*s %lu %*d %*d %*s %*s %*s %s", &Pid, Cmd))
{
}
else if (2 == sscanf (line, "some-other-format", &Pid, Cmd))
{
}
else
{
fprintf(stderr, "Unable to parse '%s'\n", line);
}
}
此外,通过指定sscanf()
应写入Cmd
的最大字符数,防止潜在的缓冲区溢出。这应该小于Cmd
的大小,为终止的空字符留出空间。例如:
if (2 == sscanf(line, "%lu %255s", &Pid, Cmd))
返回分配的数量。根据EOF
进行检查是不够的,因为有些赋值可能已经完成,而其余的赋值则没有,这意味着后续代码将处理过时或未初始化的值。当格式意外时,以下循环将在第一行停止处理,并避免过时的值:
while ( 2 == fscanf (FileDesc, "%*s %lu %*d %*d %*s %*s %*s %s", &Pid, Cmd))
{
}
一种改进的解决方案是先读取一行,然后使用解析读取的行。这将允许您检测EOF
,并允许多次尝试使用不同格式解析该行:
char line[1024];
while (fgets(line, sizeof(line), stdin))
{
if (2 == sscanf (line, "%*s %lu %*d %*d %*s %*s %*s %s", &Pid, Cmd))
{
}
else if (2 == sscanf (line, "some-other-format", &Pid, Cmd))
{
}
else
{
fprintf(stderr, "Unable to parse '%s'\n", line);
}
}
此外,通过指定sscanf()
应写入Cmd
的最大字符数,防止潜在的缓冲区溢出。这应该小于Cmd
的大小,为终止的空字符留出空间。例如:
if (2 == sscanf(line, "%lu %255s", &Pid, Cmd))
返回分配的数量。根据EOF
进行检查是不够的,因为有些赋值可能已经完成,而其余的赋值则没有,这意味着后续代码将处理过时或未初始化的值。当格式意外时,以下循环将在第一行停止处理,并避免过时的值:
while ( 2 == fscanf (FileDesc, "%*s %lu %*d %*d %*s %*s %*s %s", &Pid, Cmd))
{
}
一种改进的解决方案是先读取一行,然后使用解析读取的行。这将允许您检测EOF
,并允许多次尝试使用不同格式解析该行:
char line[1024];
while (fgets(line, sizeof(line), stdin))
{
if (2 == sscanf (line, "%*s %lu %*d %*d %*s %*s %*s %s", &Pid, Cmd))
{
}
else if (2 == sscanf (line, "some-other-format", &Pid, Cmd))
{
}
else
{
fprintf(stderr, "Unable to parse '%s'\n", line);
}
}
此外,通过指定sscanf()
应写入Cmd
的最大字符数,防止潜在的缓冲区溢出。这应该小于Cmd
的大小,为终止的空字符留出空间。例如:
if (2 == sscanf(line, "%lu %255s", &Pid, Cmd))
您能告诉我们该文件中包含的数据格式吗。@Ajay,该文件包含linux命令“ps-ef”的重定向输出。您能告诉我们该文件中包含的数据格式吗。@Ajay,该文件包含linux命令“ps-ef”的重定向输出您能告诉我们文件中包含的数据是什么格式吗。@Ajay,该文件包含linux命令“ps-ef”的重定向输出,您能告诉我们文件中包含的数据是什么格式吗。@Ajay,该文件包含linux命令“ps-ef”的重定向输出,将于本周进行表决,但我想你是想在第二段代码中使用
sscanf
和line
。(如果我正确地遵循了你的逻辑,这对我来说永远是一个废话)。@WhozCraig,谢谢,这就是我的意思。已编辑。安全、正确地使用scanf是非常重要的。回答得很好。我将对此进行投票,但我认为你是想在第二段中使用sscanf
和line
。(如果我正确地遵循了你的逻辑,这对我来说永远是一个废话)。@WhozCraig,谢谢,这就是我的意思。已编辑。安全、正确地使用scanf是非常重要的。回答得很好。我将对此进行投票,但我认为你是想在第二段中使用sscanf
和line
。(如果我正确地遵循了你的逻辑,这对我来说永远是一个废话)。@WhozCraig,谢谢,这就是我的意思。已编辑。安全、正确地使用scanf是非常重要的。回答得很好。我将对此进行投票,但我认为你是想在第二段中使用sscanf
和line
。(如果我正确地遵循了你的逻辑,这对我来说永远是一个废话)。@WhozCraig,谢谢,这就是我的意思。已编辑。安全、正确地使用scanf是非常重要的。回答得好。