这是我的源代码。当我输入一个字符串“我在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;
}
答案 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 );
}
评论:
不要混用fgets
和scanf
。即使您已经意识到这样做所涉及的问题,但它仍然很容易弄错。最好只使用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();