C fscanf给我重复的行

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

我试图通过重定向“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 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是非常重要的。回答得好。