在结构中输入一个字符串:分段错误

时间:2022-01-22 08:57:19

So far I've been able to answer all all my questions by a dutiful search, but this one has me stumped.

到目前为止,我已经能够通过尽职尽责的回答来回答我所有的问题,但这一次让我难过。

So. I've reduced this code to the minimum necessary to produce the error. Here it is:

所以。我已将此代码减少到产生错误所需的最小值。这里是:

#include <studio.h>  

struct string {
      char *data;
} s;

int main(int argc, char *argv[])
{
    printf("Enter a string. ");
    scanf("%s\n", &s.data);
    printf("%s", s.data);

    return 0;
}

I'm using gcc 4.6.3 and compiling with -Wall -g using classic defensive programming tactics.

我正在使用gcc 4.6.3并使用经典的防御性编程策略使用-Wall -g进行编译。

I posted this from my phone, so there may be typos and autocorrect madness.

我是通过手机发布的,因此可能存在拼写错误和自动更正错误。

6 个解决方案

#1


2  

When using scanf, to read as a string using an unallocated pointer, specify the 'm' directive forcing scanf to allocate memory as needed while skipping newline. You are responsible for freeing the memory allocated to the string. scanf expects the pointer provided to be type char**.

使用scanf时,要使用未分配的指针作为字符串读取,请指定'm'指令,强制scanf在跳过换行符时根据需要分配内存。您负责释放分配给字符串的内存。 scanf期望提供的指针是char **类型。

scanf ("%m[^\n]%*c", &s.data);

The trailing %*c reads and discards the trailing newline. (be aware of this if you simply press [enter])

尾随的%* c读取并丢弃尾随换行符。 (如果你只需按[enter],请注意这一点)

#2


1  

Point 1. allocate memeory to the pointer before using it

要点1.在使用之前将指令分配给指针

s.data = calloc(DATASIZE, sizeof (char));

Recommended Alternative: malloc()

推荐替代方案:malloc()

Point 2. Use scanf() to take the input and store it.

要点2.使用scanf()获取输入并存储它。

scanf("%s", s.data);

Recommended Alternative: fgets()

推荐替代方案:fgets()

Please find below is a corrected version of your code.

请在下面找到您的代码的更正版本。

#include <stdio.h>  
#include <stdlib.h>

#define DATASIZE 128

struct string {
      char *data;
} s;

int main(int argc, char *argv[])
{
    s.data = calloc(DATASIZE, sizeof (char));
    printf("Enter a string. \n");
    scanf("%s", s.data);
    printf("Input is : %s\n", s.data);

    return 0;
}

#3


0  

You need allocated the memory by using malloc first.

您需要先使用malloc分配内存。

s.data = malloc(100);

s.data = malloc(100);

#4


0  

The fact that it's in a struct isn't the problem. The problem is that the pointer data is not initialized, and there's no memory for the stuff to be copied into.

它在结构中的事实不是问题。问题是指针数据没有初始化,并且没有内存可以复制到的东西。

This solves the problem:

这解决了这个问题:

struct string 
{
 char data [SOMEBIGNUMBER]
} s;

and so does this: keep string as it is, but allocate the space for data in main using malloc.

这样做:保持字符串不变,但使用malloc为main中的数据分配空间。

#5


0  

It seems that in this statement

似乎在这个声明中

("%s", s.data);

there is a typo. I think you mean

有一个错字。我想你的意思是

scanf("%s", s.data);

Otherwise

("%s", s.data);

is an expression with the comma operator that simply returns s.data.

是一个逗号运算符的表达式,它只返回s.data。

The first problem with your code that you have to allocate memory where you are going to write enetered data.

您的代码的第一个问题是,您必须在将要写入内存数据的位置分配内存。

For example

s.data = malloc( 256 * sizeof( char ) );

Instead of 256 you may use nay value as you like.

您可以根据需要使用nay值代替256。

The second problem is that you should use fgets instead of scanf because using the last is unsafe.

第二个问题是你应该使用fgets而不是scanf,因为使用last是不安全的。

So the main can look like

所以主要看起来像

int main( void )
{
    const size_t N = 256;

    s.data = malloc( N * sizeof( char ) );

    s.data[0] = '\0';

    printf("Enter a string (no more than %zu characters). ", N );
    fgets( s.data, N, stdin );

    printf("%s\n", s.data);

    free( s.data );

    return 0;
}

Also you may remove the new line character that will be stored in data.s after fgets.

您也可以删除fgets后将存储在data.s中的新行字符。

For example

size_t len = strlen( s.data );
if ( len && s.data[len - 1] == '\n' ) s.data[len - 1] = '\0';

#6


0  

In this use malloc for memory allocation of structure object and char pointer. below is corrected code....

在此使用malloc进行内存分配的结构对象和char指针。以下是更正后的代码....

#include <stdio.h>
#include <malloc.h>

struct string {
  char *data;
} *s;
int main(int argc, char *argv[])
{
   s = (struct string*)malloc(sizeof(struct string));
   s->data = (char*)malloc(sizeof(char) * 100);

   printf("Enter a string : ");
   scanf("%s", s->data);
   printf("%s\n", s->data);

   return 0;
}

#1


2  

When using scanf, to read as a string using an unallocated pointer, specify the 'm' directive forcing scanf to allocate memory as needed while skipping newline. You are responsible for freeing the memory allocated to the string. scanf expects the pointer provided to be type char**.

使用scanf时,要使用未分配的指针作为字符串读取,请指定'm'指令,强制scanf在跳过换行符时根据需要分配内存。您负责释放分配给字符串的内存。 scanf期望提供的指针是char **类型。

scanf ("%m[^\n]%*c", &s.data);

The trailing %*c reads and discards the trailing newline. (be aware of this if you simply press [enter])

尾随的%* c读取并丢弃尾随换行符。 (如果你只需按[enter],请注意这一点)

#2


1  

Point 1. allocate memeory to the pointer before using it

要点1.在使用之前将指令分配给指针

s.data = calloc(DATASIZE, sizeof (char));

Recommended Alternative: malloc()

推荐替代方案:malloc()

Point 2. Use scanf() to take the input and store it.

要点2.使用scanf()获取输入并存储它。

scanf("%s", s.data);

Recommended Alternative: fgets()

推荐替代方案:fgets()

Please find below is a corrected version of your code.

请在下面找到您的代码的更正版本。

#include <stdio.h>  
#include <stdlib.h>

#define DATASIZE 128

struct string {
      char *data;
} s;

int main(int argc, char *argv[])
{
    s.data = calloc(DATASIZE, sizeof (char));
    printf("Enter a string. \n");
    scanf("%s", s.data);
    printf("Input is : %s\n", s.data);

    return 0;
}

#3


0  

You need allocated the memory by using malloc first.

您需要先使用malloc分配内存。

s.data = malloc(100);

s.data = malloc(100);

#4


0  

The fact that it's in a struct isn't the problem. The problem is that the pointer data is not initialized, and there's no memory for the stuff to be copied into.

它在结构中的事实不是问题。问题是指针数据没有初始化,并且没有内存可以复制到的东西。

This solves the problem:

这解决了这个问题:

struct string 
{
 char data [SOMEBIGNUMBER]
} s;

and so does this: keep string as it is, but allocate the space for data in main using malloc.

这样做:保持字符串不变,但使用malloc为main中的数据分配空间。

#5


0  

It seems that in this statement

似乎在这个声明中

("%s", s.data);

there is a typo. I think you mean

有一个错字。我想你的意思是

scanf("%s", s.data);

Otherwise

("%s", s.data);

is an expression with the comma operator that simply returns s.data.

是一个逗号运算符的表达式,它只返回s.data。

The first problem with your code that you have to allocate memory where you are going to write enetered data.

您的代码的第一个问题是,您必须在将要写入内存数据的位置分配内存。

For example

s.data = malloc( 256 * sizeof( char ) );

Instead of 256 you may use nay value as you like.

您可以根据需要使用nay值代替256。

The second problem is that you should use fgets instead of scanf because using the last is unsafe.

第二个问题是你应该使用fgets而不是scanf,因为使用last是不安全的。

So the main can look like

所以主要看起来像

int main( void )
{
    const size_t N = 256;

    s.data = malloc( N * sizeof( char ) );

    s.data[0] = '\0';

    printf("Enter a string (no more than %zu characters). ", N );
    fgets( s.data, N, stdin );

    printf("%s\n", s.data);

    free( s.data );

    return 0;
}

Also you may remove the new line character that will be stored in data.s after fgets.

您也可以删除fgets后将存储在data.s中的新行字符。

For example

size_t len = strlen( s.data );
if ( len && s.data[len - 1] == '\n' ) s.data[len - 1] = '\0';

#6


0  

In this use malloc for memory allocation of structure object and char pointer. below is corrected code....

在此使用malloc进行内存分配的结构对象和char指针。以下是更正后的代码....

#include <stdio.h>
#include <malloc.h>

struct string {
  char *data;
} *s;
int main(int argc, char *argv[])
{
   s = (struct string*)malloc(sizeof(struct string));
   s->data = (char*)malloc(sizeof(char) * 100);

   printf("Enter a string : ");
   scanf("%s", s->data);
   printf("%s\n", s->data);

   return 0;
}