c语言字符指针、字符串初始化问题

本文探讨了在C语言中使用scanf初始化char*变量导致的段错误问题。作者通过实例代码解释了问题原因在于没有为scanf提供足够的内存空间,并提出了解决方案,包括使用动态内存分配和使用字符数组。文章强调了正确处理字符串输入的重要性,以避免内存访问错误。
摘要由CSDN通过智能技术生成

之前,我在做图的存储结构的时候,用邻接矩阵来表示一张图,遇到一个段错误问题:

上面只要一输入一条边,就会出现段错误,而段错误,往往就是内存地址访问出错,比如数组越界,访问了未分配的地址,访问系统已经分配的地址,都会出错,于是我将错误定位到输入边的这个位置

上面就是我在循环之前,定义了两个字符指针,准备用来存放字符串,但是只要一scanf之后,只要访问其中某一个变量就会出现段错误,难道是说这个地址不能别访问?

于是我做了一个实验,如下操作:

直接上代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>



void test(char* str)
{
	printf("str=%s\n", str);
	if (strcmp("love", str) == 0) {
		printf("哈哈,字符串相等\n");
	}
	else 
	{
		printf("字符串不相等\n");
	}
}

int main()
{
	char* v1;
	scanf("%s", &v1);
	test(v1);
	system("pause");
	return 0;
}

   然后就会内存地址访问错误

   那我又改成如下代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>



void test(char* str)
{
	printf("str=%s\n", str);
	if (strcmp("love", str) == 0) {
		printf("哈哈,字符串相等\n");
	}
	else 
	{
		printf("字符串不相等\n");
	}
}

int main()
{
	
	test("love");

	system("pause");
	return 0;
}

运行正常:

        

        

换句话说,问题就出在:

         

 也就是说,不能用sacnf来初始化char*,下面我们就来分析一下:

  

那么就是说,char* p存放的是常量字符串的地址,那我们就不能用scanf来初始化 ,因为如果用scanf来初始化,我们根本在常量区没有空间指向。而且就算有空间指向了常量区,也不能用scanf去初始化,比如如下:

        

因为常量区的数据读写本来就是一旦定义了就不允许改动的 

如果我们就要scanf一个char *呢?

那么这里问题就来了,scanf不能初始化一个char *变量的本质是什么?

其实说的简单一点就是没有一个指向足够大空间的指针,来存储我们输入的字符串

那这样来说,我们给scanf去malloc一片地址空间不就可以了吗?

下面直接贴一下代码

#include <cstdio>
#include <cstdlib>
#include <cstring>

/**
 * 测试:在使用 %s 时,
 * 你需要为它提供一个指向足够大空间的指针,以便存储输入的字符串。
 */

int main()
{
    //堆上面给了10个char的空间
    char* res = (char*)malloc(sizeof(char) * 10);
    scanf("%s",res);
    printf("\n------\n");
    printf("result string: %s\n",res);
    return 0;
}



运行结果:

我们输入一个love you

 

我们看到输入了love you只给我们打印了love,这个没有全部打出来的原因就是,scanf遇到空格,你在输入字符串中间有空格就表示输入已经结束了 。我们当然可以采用另外一种输入格式来做,可以解决这个问题

上面的意思就是读取除了换行符之外的所有字符

 当然了,这个不是问题的重点,重点是我们可以接收scanf输入了,OK。

那一般情况下我们用scanf怎么初始化一个字符串呢

这里我们第一时间考虑的应该是一个字符数组,代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>



void test(char* str)
{
	printf("str=%s\n", str);
	if (strcmp("love", str) == 0) {
		printf("哈哈,字符串相等\n");
	}
	else 
	{
		printf("字符串不相等\n");
	}
}

int main()
{
	char str[10] = "pxx";//OK,并且带有'\0'
	scanf("%s", str);
	test(str);//char*指向了一个数组空间
	system("pause");
	return 0;
}

 运行结果:

        

对于test来说,相当于用char* str指向了char str[10]的这片数组空间,这个时候char*  str有指向了,并且可以改动,我们既可以用scanf来直接赋值。

        代码改动如下:

                 

        运行结果:

         

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值