Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C getline()函数出现分段错误?_C_Linux_Getline - Fatal编程技术网

C getline()函数出现分段错误?

C getline()函数出现分段错误?,c,linux,getline,C,Linux,Getline,我正在Linux上的终端上学习C,我用文本做了一个小游戏,所以一切都在运行,特别是我的大循环,如果玩家想重新启动游戏,我只是在开始时添加了一个dump,Enter your pseudo 当我进入它时它不起作用,它说我 Segmentation Error , core dumped 以下是所有代码,最重要的是第一行,因为所有其他代码都运行良好: #include <stdio.h> #include <stdlib.h> #include <time.h>

我正在Linux上的终端上学习C,我用文本做了一个小游戏,所以一切都在运行,特别是我的大循环,如果玩家想重新启动游戏,我只是在开始时添加了一个dump,Enter your pseudo

当我进入它时它不起作用,它说我

Segmentation Error , core dumped
以下是所有代码,最重要的是第一行,因为所有其他代码都运行良好:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
int main (void) {
  // déclaration des variables
  bool essais8  = false ;
  bool essais10 = false ;
  bool essais12 = false;
  bool essais14 = false;
  bool condition = true;
  bool condition_diff = false;
  bool condition_recommencer = false;
  bool condition_bonus1 = true;
  bool condition_bonus2 = true;
  bool condition_bonus3 = true;
  char* buffer;
  char* recommencer;
  char* pseudo ;
  size_t bufsize = 32;
  size_t characters;
  int difficulte;
  int sheitan = 0;
  int sheitan2 = 0;
  int a;
  int bonus1;
  int bonus2;
  int bonus3;
  int ecart;
  int essais;
  int nb_bonus2;
  srand(time(NULL));




  // on récupère le pseudo du joueur
   printf("Salut ! Quel est ton nom ? ");
  characters = getline(&buffer,&bufsize,stdin);
  pseudo = buffer;
// after this I have the segmentation errror




  while (condition == true) {   // Boucle de recommencement du Jeu
// here is the big game that was functioning perfectly before I add the pseudo option on top.
  }
  printf("Fin du programme \n");
  return(0);
}
您忘记初始化缓冲区了。在缓冲任何输入之前,最好使用\n或else调用结束格式控制字符串

未初始化的指针包含垃圾。使用它是必要的。是的

所以我的建议是编码

size_t bufsiz = 64;
char *buffer = malloc(bufsiz);
if (!buffer) { perror("malloc buffer"); exit(EXIT_FAILURE); };
后来

printf("Salut ! Quel est ton nom ?\n");
characters = getline(&buffer,&bufsize,stdin);
下次编译时启用所有警告和调试信息,所以如果使用,请编译代码gcc-Wall-Wextra-g。你会得到一些警告

当然,阅读和阅读

在Linux上,在您的特定情况下,您可能会对使用而不是


不要忘记阅读您正在使用的每个函数的文档,例如,如果它是标准的C函数。

'buffer'变量指向某个垃圾内存地址。您需要首先使用“malloc”函数分配必要的内存,或者将“buffer”设置为静态数组,而不是指针。

可以两种不同的方式使用:

读入调用者提供的缓冲区。 读取时分配内存。 使用1。初始化传递给指向有效内存的指针,并传递有效内存的大小

#define INITIAL_SIZE (42)

int main(void)
{  
  char * buffer = malloc(INITIAL_SIZE * sizeof *buffer);
  size_t bufsize = INITIAL_SIZE;
  ssize_t characters = getline(&buffer, &bufsize, stdin);
  if (-1 == characters)
  {
     /* handle error. */
  }
  else
  {
     /* use buffer */
  }

  free(buffer); /* Free buffer. */
}
使用2。初始化传递给NULL的指针,并将0作为大小传递

注意:getline返回ssize\u t而不是size\u t。

是一个函数,它将行读入动态分配的缓冲区,允许任何长度的行仅受可用内存量的限制。它返回读取的字符数,如果没有更多输入或发生错误,则返回-1

下面是一个示例使用模式:

    char   *line = NULL;
    size_t  size = 0;
    ssize_t len;

    while (1) {

        len = getline(&line, &size, stdin);
        if (len < 1)
            break;

        /* Do something with the input line */

    }
您希望将指针清除为NULL,并将大小清除为零的原因是,这样您就不会意外地尝试访问已释放的内存,但您可以调用getline&line,&size,handle来读取更多行,因为调用只会识别出它没有缓冲区,并将分配一个新的缓冲区

如果小心的话,可以按任何方式操纵动态数据。例如:

while (1) {
    char   *line = NULL;
    size_t  size = 0;
    ssize_t len;

    len = getline(&line, &size, stdin);
    if (len < 1) {
        free(line);
        break;
    }

    /* Do something with the contents of the line */

    free(line);
}
如果我们将上述内容保存为example.c,并使用gcc-Wall-O2 example.c-o example进行编译,然后运行程序,将文本文件名作为参数提供给它,例如./example.c,它将输出如下内容

example.c: Line 1: '#define _POSIX_C_SOURCE 200809L' (31 of 33 characters)
example.c: Line 2: '#include <stdlib.h>' (19 of 20 characters)
example.c: Line 3: '#include <locale.h>' (19 of 20 characters)
example.c: Line 4: '#include <string.h>' (19 of 20 characters)
example.c: Line 5: '#include <stdio.h>' (18 of 19 characters)
example.c: Line 6: '#include <ctype.h>' (18 of 19 characters)
example.c: Line 7: '#include <errno.h>' (18 of 19 characters)
example.c: Line 8: '' (0 of 1 characters)
example.c: Line 9: 'int main(int argc, char *argv[])' (32 of 33 characters)
在linenum++行之后,查看文本文件的第七行发生了什么。它们被跳过,即使释放了缓冲区,也不会发生什么不好的事情,因为continue会启动while循环体的下一个迭代,因为下一个getline只会动态地分配一个新行

如果您决定保留一部分行的副本,只需计算需要为字符串nul\0的结尾添加一个的长度,始终为C中的重复大小分配多个字符,即char==1;所以malloc等人计算数据中要分配给memcpy的字符数,并添加终止nul。比如说,

char *sdup(const char *const source, const size_t  length)
{
    char *s;

    s = malloc(length + 1);
    if (!s) {
        /* Either return NULL, or: */
        fprintf(stderr, "sdup(): Not enough memory for %zu chars.\n", length + 1);
        exit(EXIT_FAILURE);
    }

    if (length > 0)
        memcpy(s, source, length);

    s[length] = '\0';
    return s;
}

如果您希望完整的字符串一直到字符串nul的末尾,可以使用POSIX.1-2008。

没有一个指针被初始化为指向有效的memory@UnholySheep ... 或空或0。谢谢,它成功了!但是,如果我的缓冲区没有显示任何内存,为什么它在我所有的程序中都能正常工作,而且从来没有出现过这个错误?请按照我在回答中给出的所有链接进行操作。非常感谢!祝你有美好的一天!您需要首先分配[…]内存,但不一定。请参阅我关于使用getline.Outsh的替代方案的答案@名义动物修复!Thx!:}
#define _POSIX_C_SOURCE  200809L
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    unsigned long  linenum;
    char          *line = NULL, *in, *out, *end;
    size_t         size = 0, n;
    ssize_t        len;
    FILE          *src;
    int            arg;

    if (!setlocale(LC_ALL, ""))
        fprintf(stderr, "Warning: Your C library does not support your current locale.\n");

    if (argc < 2) {
        fprintf(stderr, "\n");
        fprintf(stderr, "Usage: %s FILENAME [ FILENAME ... ]\n", argv[0]);
        fprintf(stderr, "\n");
        exit(EXIT_FAILURE);
    }

    for (arg = 1; arg < argc; arg++) {

        src = fopen(argv[arg], "r");
        if (!src) {
            fprintf(stderr, "%s: %s.\n", argv[arg], strerror(errno));
            free(line);
            exit(EXIT_FAILURE);
        }

        linenum = 0;

        while (1) {

            len = getline(&line, &size, src);
            if (len < 1)
                break;

            linenum++;

            /* First character in the line read: */
            in = line;
            out = line;

            /* Pointer to the end-of-string character on the line: */
            end = line + len;

            /* Skip all leading whitespace characters. */
            while (in < end && isspace((unsigned char)(*in)))
                in++;

            /* Character copy loop. */
            while (in < end)
                if (isspace((unsigned char)(*in))) {
                    /* Replace consecutive whitespace characters with spaces. */
                    *(out++) = ' ';
                    do {
                        in++;
                    } while (in < end && isspace((unsigned char)(*in)));
                } else {
                    /* Copy all other characters as-is. */
                    *(out++) = *(in++);
                }

            /* There may be a single space before out. Backtrack it, if so. */
            if (out > line && out[-1] == ' ')
                out--;

            /* Mark the end of the string at out. */
            *out = '\0';

            /* Calculate the new length, just for output purposes. */
            n = (size_t)(out - line);

            /* Print the line. */
            printf("%s: Line %lu: '%s' (%zu of %zd characters)\n",
                   argv[arg], linenum, line, n, len);

        }
        if (!feof(src) || ferror(src)) {
            fprintf(stderr, "%s: Read error.\n", argv[arg]);
            fclose(src);
            free(line);
            exit(EXIT_FAILURE);
        }
        if (fclose(src)) {
            fprintf(stderr, "%s: Error closing file: %s.\n",
                            argv[arg], strerror(errno));
            free(line);
            exit(EXIT_FAILURE);
        }
    }

    free(line);
    line = NULL;
    size = 0;

    return EXIT_SUCCESS;
}
example.c: Line 1: '#define _POSIX_C_SOURCE 200809L' (31 of 33 characters)
example.c: Line 2: '#include <stdlib.h>' (19 of 20 characters)
example.c: Line 3: '#include <locale.h>' (19 of 20 characters)
example.c: Line 4: '#include <string.h>' (19 of 20 characters)
example.c: Line 5: '#include <stdio.h>' (18 of 19 characters)
example.c: Line 6: '#include <ctype.h>' (18 of 19 characters)
example.c: Line 7: '#include <errno.h>' (18 of 19 characters)
example.c: Line 8: '' (0 of 1 characters)
example.c: Line 9: 'int main(int argc, char *argv[])' (32 of 33 characters)
        if (linenum == 7) {
            /* We skip line 7, and even destroy it! Muahhahah! */
            free(line);
            line = NULL;
            size = 0;
            continue;
        }
char *sdup(const char *const source, const size_t  length)
{
    char *s;

    s = malloc(length + 1);
    if (!s) {
        /* Either return NULL, or: */
        fprintf(stderr, "sdup(): Not enough memory for %zu chars.\n", length + 1);
        exit(EXIT_FAILURE);
    }

    if (length > 0)
        memcpy(s, source, length);

    s[length] = '\0';
    return s;
}