用C中的另一个字符串替换字符串的一部分

时间:2014-03-30 17:05:38

标签: c string

这是我的源代码。当我输入一个字符串“我在CSE第二年。”并且由ECE 3rd替换CSE 2nd(即loc 9到15),我在字符串的末尾得到一些垃圾桶。在rslt2字符串的开头还有一个换行符。 rslt2有问题。有人可以纠正错误吗?

//splitting a string and replace latter part of string by another string
#include<stdio.h>
#include<string.h>
int main()
{
    int i,count=0,loc2,scount=0,rcount=0,loc=0;     //scount represents counter for subset and rcount for replacement and loc from where we will split the string
    char str[100],sub[100],newss[100],rslt[100],rslt2[100]; //newss=new substr, rslt and rslt2=former and latter part of original string
    printf("Enter a String:\n");
    fgets(str,100,stdin);
    printf("\nString Entered by User:\n");
    fflush(stdin);
    puts(str);
    printf("\nLoc Char\n");         //Creates Colums 'Char' and 'Loc'
    for(i=0;str[i]!='\0';i++)
    {
        count++;                                //Counts length of String
        printf("%d. %c\n",count,str[i]);    //Prints Characters with it its Corresponding Location
    }
    printf("\n\nLength of String: %d\n\n",count);
    printf("Enter the locations of Characters from where subset will start and end: \n");
    scanf("%d%d",&loc,&loc2);       //stores indices of begining and end of substring
    printf("\n\nSubset formed from Existing String:\n");
    for(i=loc-1;i<loc2;i++)
    {
        scount++;
        sub[i]=str[i];              //stores substring in "sub"
        printf("%c",sub[i]);
    }
    printf("\n\nLength of Subset: %d\n",scount);
    for(i=0;i<(loc-1);i++)
    {
        rslt[i]=str[i];         //Stores former part of string in resultant string
    }
    for(i=loc2;i<strlen(str);i++)
    {
        rslt2[i]=str[i];        //Stores latter part of string in resultant string2
    }
    printf("\n\nEnter a Replacement for Subset(Of Equal Length as that of Subset):\n");
    fflush(stdin);
    fgets(newss,100,stdin);
    for(i=0;newss[i]!='\0';i++)
    rcount++;
    printf("\n\nLength of New Subset: %d\n",rcount-1);  //-1 to subtract length of null char
    if(rcount-1!=scount)        //to check whether replacement string and substring are of same len
    printf("\nSince length of both subsets is not same. \nHence Replacement is Not Possible\n");
    else        //Concatination of 3 substrings
    {
        printf("\nResultant String:\n");
        for(i=0;i<(loc-1);i++)
        printf("%c",rslt[i]);
        printf("\n");
        for(i=0;newss[i]!='\0';i++)
        printf("%c",newss[i]);
        for(i=loc2;rslt2[i]!='\0';i++)
        printf("%c",rslt2[i]);
    }
        return 0;
}

2 个答案:

答案 0 :(得分:0)

以下是如何实施该计划的示例。

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

#define MAXL 100

int main( void )
{
    int count, lengthI, lengthR, start, end;
    char initial[MAXL], replacment[MAXL], range[MAXL], result[MAXL];

    // get user input
    printf( "Initial string: " );
    fflush( stdout );
    fgets( initial, MAXL, stdin );

    printf( "Replacement string: " );
    fflush( stdout );
    fgets( replacment, MAXL, stdin );

    printf( "Start and end: ");
    fflush( stdout );
    fgets( range, MAXL, stdin );
    count = sscanf( range, "%d%d", &start, &end );       // indices of beginning and end of range in initial string

    // remove newline character from the input strings, if necessary
    lengthI = strlen( initial );
    if ( lengthI > 0 && initial[lengthI - 1] == '\n' )
        initial[--lengthI] = '\0';

    lengthR = strlen( replacment );
    if ( lengthR > 0 && replacment[lengthR - 1] == '\n' )
        replacment[--lengthR ] = '\0';

    // range checking to verify that user inputs are valid and the resulting string will fit into the buffer
    if ( count != 2 || start < 0 || start > lengthI || end < start || end > lengthI )
    {
        fprintf( stderr, "Invalid start and end values\n" );
        exit( 1 );
    }
    if ( lengthI + lengthR - (end - start) + 1 > MAXL )
    {
        fprintf( stderr, "Resulting string would be too long\n" );
        exit( 2 );
    }

    // create a new string with the substring replaced
    if ( start > 0 )                                    // copy characters from the initial string up to the start index
        strncpy( result, initial, start );              // note: this step may leave the result string unterminated

    strcpy( &result[start], replacment );               // append the repacement string 
                                                        // guarantees the result string is terminated 

    if ( end < lengthI )                                // append characters from the initial that are after the end index
        strcat( result, &initial[end] );                // terminates the result string (provided that strcat is called) 

    // print the result
    printf( "%s\n", result );
}

评论:

不要混用fgetsscanf。即使您已经意识到这样做所涉及的问题,但它仍然很容易弄错。最好只使用fgets读取行,然后根据需要使用sscanf进行解析。

fflush(stdin)是非标准的。 fflush只能保证在stdout上工作。在某些系统上,fpurge可用于擦除未读输入。

当处理C中的字符串(也就是字符数组)时,范围检查是必不可少的。缓冲区溢出是导致C程序崩溃,意外行为和安全漏洞的首要原因。始终检查用户输入范围,并始终验证新创建的字符串是否适合所提供的缓冲区。

始终确保新创建的字符串以空字符结尾(也称为&#39; \ 0&#39;),并确保在计算缓冲区大小时包含该空字符。

请注意,在示例代码中,strncpy可能会使字符串无法终止。随后对strcpy的调用将终止该字符串。 strcat函数也将终止字符串。但是,对strcat的调用是基于用户输入的条件。因此,如果没有调用strcpy&#39;,我们还有额外的工作要做,以保证字符串获得强制的空终止符。

答案 1 :(得分:-1)

使用否定的scanf即scanf(" %[^\n]",str_name);而不是gets();