Chinaunix

标题: 小写转大写程序,显示段错误 [打印本页]

作者: dagobert1989    时间: 2011-05-04 14:48
标题: 小写转大写程序,显示段错误
#include <stdio.h>

void uppers(char *s,char *us)
{
        for(;*s!='\0';s++,us++)
        {
                if(*s>='a'&&*s<='z')
                        *us=*s-32;
                else
                        *us=*s;
        }
}

int main()
{
        char *s,*us;
        char ss[20];
        printf("Please input a string:\n");
        scanf("%s",ss);
        s=ss;
        uppers(s,us);
        printf("The result is:\n%s\n",us);
}

输入字符按理来说应该显示的是大写字母;
但我输入一段小写字母后,它显示的是:段错误.
这是为什么啊?
请高手指教!
作者: hellioncu    时间: 2011-05-04 14:52
输入的字符串太长了
作者: cobras    时间: 2011-05-04 14:52
us=s=ss;
作者: huoest    时间: 2011-05-04 15:28
US那个指针没有指向正确的位置,所以才会段错误。
作者: Cindinx    时间: 2011-05-04 16:01
回复 1# dagobert1989


緩沖區溢出錯誤的經典的例子啊...借用一下您的程式碼, 給徒弟們講解如何? 先在此謝過啦, 哈哈
作者: dagobert1989    时间: 2011-05-05 09:06
回复 5# Cindinx
大侠,那应该怎么改啊?
可不可以给个思路啊?
作者: Cindinx    时间: 2011-05-05 09:24
回复  Cindinx
大侠,那应该怎么改啊?
可不可以给个思路啊?
dagobert1989 发表于 2011-05-05 09:06



    在栈里面分配缓冲区没错,但是往缓冲区里写的时候要控制长度
作者: 雨夜流星    时间: 2011-05-05 09:26
转换成大写,好像只要

char c;
c & 0xDF;
就可以了吧?
作者: Cindinx    时间: 2011-05-05 09:45
转换成大写,好像只要

char c;
c & 0xDF;
就可以了吧?
雨夜流星 发表于 2011-05-05 09:26



    他的問題不是轉換的事情, 而是發生了緩沖區溢出錯誤
作者: 雨过白鹭洲    时间: 2011-05-05 09:58
回复 5# Cindinx


    溢出个毛!us指针根本就没有分配内存,它指向的是内存中的随机位置,在upper函数中又向该内存区域写入数据才导致“段错误”的


char *s,*us; // us这样只是定义一个指针而已

char us[20]; // 应该这样定义,或者分配一块内存
char ss[20];
作者: Cindinx    时间: 2011-05-05 10:01
回复 10# 雨过白鹭洲

scanf("%s",ss);

這個函數的作用不是往數組ss里面寫入么, 如果溢出了, 就會寫壞上一級函數的堆棧幀.
作者: 雨过白鹭洲    时间: 2011-05-05 13:25
回复 11# Cindinx


    你那函数里面的实现啊,明显是往char *us里面写东西,这是个未初始化的指针变量呢。。

坦白地说,这和溢出无关!
作者: Cindinx    时间: 2011-05-05 13:36
回复 12# 雨过白鹭洲


    这个地方也有问题,使用了野指针
作者: szlishun    时间: 2011-05-05 13:54
雨过白鹭洲 是对的
作者: hyrz183    时间: 2011-05-05 16:01
没初始化造成的结果啊,导致越界
作者: liupingforarm    时间: 2011-05-05 19:55
我也觉得是10楼对的,初始化一个字符串最好用字符数组,而不是字符指针,你没有初始化吧呵呵。
作者: woshizzb    时间: 2011-05-05 20:17
楼主调用scanf的地方的确是有溢出的危险, 但10楼所说才是root cause。
作者: 0xC1988    时间: 2011-05-05 21:44
us的问题
作者: ttldreams    时间: 2011-05-05 23:09
us没有初始化,也没有指向有效内存
作者: shenlanyouyu    时间: 2011-05-06 10:08
10楼是对的,我一看us就发现us是个野指针!
作者: noiplee    时间: 2011-05-06 12:24
10楼正解
作者: cobras    时间: 2011-05-06 13:12
LZ的uppers支持两种用法:1、us==s,即修改原内容;2、us != s,拷贝s到us。要求us < s || u >= s+LENGTH(s);
作者: jsntwjw    时间: 2011-05-08 08:11
10楼是正解,
转换后的字符数组,应该分配空间。
作者: 天堂Guy    时间: 2011-05-08 10:22
#include <stdio.h>
#include <stdlib.h>
void uppers(char *s,char *us)
{
       
        for(;*s!='\0';s++,*us++)
        {
                if(*s>='a'&&*s<='z')
                       *us=*s-32;
                else
                        *us=*s;
                               
        }
                *us = '\0';
               
}
int main(void)
{
        char *s,us[20];
        char ss[20];
        printf("Please input a string:\n");
        scanf("%s",ss);
        s=ss;
        uppers(s,us);
        printf("The result is:\n%s\n",us);
        getchar();
        return 0;
}
这是你问题的代码,很简单的题,楼主还是任重道远,一起努力吧。。。
作者: oxangen    时间: 2011-05-08 22:54
提示: 作者被禁止或删除 内容自动屏蔽
作者: zheguzai    时间: 2011-05-09 09:05
us就是个野指针啊
作者: pinkguy    时间: 2011-05-09 14:54
本帖最后由 pinkguy 于 2011-05-09 15:07 编辑
#include

void uppers(char *s,char *us)
{
        for(;*s!='\0';s++,us++)
        {
          ...
dagobert1989 发表于 2011-05-04 14:48



#include <stdio.h>

void uppers(char *s,char *us)
{
    for(;*s!='\0';s++,us++)
    {   
        if(*s>='a'&&*s<='z')
            *us=*s-32;
        else
            *us=*s;
    }   
    *us = '\0'; /* must end with '\0' */
}

int main()
{
    /* char *s,*us; */
    char *s,us[20];
    char ss[20];
    printf("Please input a string:\n");
    /* scanf("%s",ss); */
    fgets(ss, sizeof(ss), stdin); /* much safer */
    s=ss;
    uppers(s,us);
    printf("The result is:\n%s\n",us);
    return 0;
}
作者: jy02107028    时间: 2011-05-09 18:44
us初始化为数组或者使用malloc分配堆中内存
顶10楼
作者: believetruelove    时间: 2011-05-09 19:22
10楼正解.
楼主记住一点,段错误就是对一此内存段进行非法操作引发的错误,常见的非法操作包括对空指针赋值,修改字符串常量,对野指针(未分配合法空间的指针)赋值。
你举的例子中us就是野指针,由于它指向内存区域是随机的,当指向一些指读区域如操作系统占用的内存区域时对其进行写操作就会引发段错误。
解决方法就是对症下药,1.让us指向栈上 分配空间(静态数组)2.让us指向堆上分配空间(用malloc等函数)。
作者: samkli    时间: 2011-05-10 11:22
这个程序有两个错误:一个是确实是溢出了,另一个是确实是没有初始化指针。

程序运行失败是因为指针没有被初始化
即是初始化了后,也有溢出的问题。
上面27楼的那个代码应该是没什么问题的了。

如果楼主一定要用scanf函数的话应该要在 uppers 函数的末端加上 *us = '\0' 。


#include <stdio.h>

void uppers(char *s,char *us)
{
        for(;*s!='\0';s++,us++)
        {
                if(*s>='a'&&*s<='z')
                        *us=*s-32;
                else
                        *us=*s;
        }
                *us = '\0'; // 添加
}

int main(void)
{
        char *s,*us;
        char ss[20];
                char uss[20]; // 添加
        printf("Please input a string:\n");
        scanf("%s",ss);
        s=ss;
                us = uss; // 添加
        uppers(s,us);
        printf("The result is:\n%s\n",us);
}

作者: snow888    时间: 2011-05-10 15:10
回复  dagobert1989


緩沖區溢出錯誤的經典的例子啊...借用一下您的程式碼, 給徒弟們講解如何? 先在此 ...
Cindinx 发表于 2011-05-04 16:01



   
作者: Cindinx    时间: 2011-05-12 15:10
回复 25# oxangen


    不, 我一直是大陸的, 因為心情原因喜歡用繁體
作者: oxangen    时间: 2011-05-16 18:38
提示: 作者被禁止或删除 内容自动屏蔽
作者: oxangen    时间: 2011-05-16 18:39
提示: 作者被禁止或删除 内容自动屏蔽
作者: Cindinx    时间: 2011-05-16 19:55
回复  Cindinx


    有些术语大陆跟台湾稍微有点区别
oxangen 发表于 2011-05-16 18:39



    台灣有的時候音譯或者翻譯得比較大白話
作者: duwei211    时间: 2011-05-16 20:07
us指哪呢?us最后指尾部了,不要直接对参数指针进行自增啊,可以定义外面个指针变量指向它再操作,或者进行+i操作




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2