正在跳过获取stdin的Getline

时间:2014-10-30 15:43:36

标签: c stdin getline

我正在尝试从控制台中的用户那里获得输入,但是我的代码中的函数getline()遇到了问题:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <memory.h>
#include <sys/wait.h>
#include <errno.h>
int main(int argc, char *argv[])
{
    //check that the number of arguments given is valid
    if (argc != 2){
        printf("Error: arguments. \nThe file should only take one argument which is the name of the level\n");
        exit(1);
    }
    char test[5];
    int nb_lettres=strlen(argv[1]);
    strncpy(test,argv[1]+nb_lettres-4,4);
    //check that the file given is either a .tgz or a .tar
    test[4]='\0';
    if(strcmp(test,".tar")!=0 && strcmp(test,".tgz")!=0)
    {
        printf("Error: arguments. \nThe argument should be a file having the extension .tar or .tgz \n");
        exit(2);
    }
    int status; //START OF THE PART CONTAINING THE PROBLEM
    pid_t pid;
    //create the folder then move to it, then extract the tar
    if((pid=fork())!=0){
        if(fork()){
            execlp("mkdir","mkdir","leaSHdir",NULL);
        }
        //waiting to make sure we don't try to go in the folder before it's fully created
        wait(&status);
        execlp("tar","tar", "-xf", argv[1], "-C", "leaSHdir/",NULL);
    }
    waitpid(pid,&status,0);
    printf("Extracting the files..\n");
    sleep(1);   //END OF THE PART CONTAINING THE PROBLEM
    //Read the meta file
    FILE *file;
    chdir("./leaSHdir");

    file=fopen("meta","r");
    if (file==NULL){
        //  printf("Oh dear, something went wrong with read()! %s\n", strerror(errno));
        printf("Error: meta. \nImpossible to read the meta file. Please check that it does exist (without looking in, vile cheater)\n");
        exit(3);

}
char *line=NULL;
size_t len=0; 
        //Saving the commands which will be used by the user
char *result=NULL;
char **commands = malloc(5 * sizeof *commands);
int i=0;
if(commands==NULL){
    printf("Error: memory. \nA problem occured with the memory while creating a pointer\n");
    exit(4);
}
while(getline(&line,&len,file)!=-1){
    if(strstr(line,"$")!=NULL){
        commands[i]=(malloc(strlen(line)));
        strcpy(commands[i],line+2); 
                    //if the array is full,we add space for the next incoming command
        if(i >= 4){
            commands=realloc(commands,sizeof *commands *(i+2));
        }
        i++;
    }
    if(line[0]=='>'){
        result=malloc(strlen(line));
        strcpy(result,line+2);
        }
}
int a = 0;
for (a = 0;a<i;a++){
    printf("%s",commands[a]);
}
printf("%s",result);
printf("Erasing meta..");
unlink("meta");
printf("meta erased.\n");
int c;

    while((c = getchar()) != '\n' && c != EOF){
        printf("rien\n");
    }
ssize_t r = getline(&line,&len,stdin); 
printf("%d '%s' %d",(int) r, line, c);
char machin[2555];
scanf("%s",machin);
printf("%s test",machin);
free(commands);
free(result);
return 0;
}   

当我执行此代码时,完全跳过最后一个getline(第一个getline正在运行,没有任何问题),我不明白为什么。我也尝试过使用不同的函数(fgets,scanf),两者都被跳过了。 提前感谢您提供的任何帮助:)

编辑: 使用ssize_t r = getline(&line,&len,stdin); printf("%d '%s' %d",(int) r, line, c);更改了错误的getline行,结果如下:

cat
ls
man
Bravo! C'est ici!//this line and the 3 other lines before are the lines read by the first getline which is working
Erasing meta..meta erased.
-1 '> Bravo! C'est ici! 
' -1

所以基本上,我甚至没有时间输入任何东西,我直接得到这个结果而不输入任何东西。此外,line的内容在第二个getline之后不会更改,因为它仍包含第一个getline的结果。 编辑2: 好吧,我想我发现问题出在哪里:基本上,它来自代码的一部分,我没有在那里提取,因为我虽然它与我当前的问题根本没有关系,所以我编辑了整个提取物充分发挥。我已经写了两条注释来标记包含问题的部分。虽然我没有看到可能导致它的原因,但考虑到这部分只包含叉子。 虽然,抱歉,伙计们,应该把整个代码放在一开始

上次修改: 弄清楚问题是什么:if((pid=fork())!=0){这意味着一旦我的叉子结束,我正在研究儿童过程,而不是像我想的那样在父亲身上。一旦我将其更改为if((pid=fork())==0){,一切正常。谢谢你的帮助:)

2 个答案:

答案 0 :(得分:1)

[编辑]

经过一些编辑:
stdin之后使用fork()时会出现OP问题。

Two processes reading the same stdin类似


代码无法接收其他输入,因为stdin已准备好达到EOF条件或罕见的IO错误。这是-1getline()的{​​{1}}返回值。 getchar()只是保留了以前的内容,因为没有任何改变。

line
  

-1&#39;&gt;好样的! C&#39; est ici!
  &#39; -1


其他问题:char c; while((c = getchar()) != '\n' && c != EOF); ssize_t r = getline(&line,&len,stdin); //getline not working printf("%d '%s' %d",(int) r, line, c); 为时已晚。

realloc()写入未分配的内存。

strcpy(commands[5],line+2);

答案 1 :(得分:0)

在getilne之前放入somtehing以消耗尾随&#39; \ n&#39;字符。例如:

while ( getchar() != '\n' );
getline(&line,&len,stdin);