나는 이것을 후회할 것이다. 그러나이 질문을 볼 때마다 나는 당신의 코드에 뭔가 다른 것을 본다. 다음은 한 줄씩입니다. 나는 아마 많은 것을 놓쳤다.
이 헤더의 올바른 이름은 "iostream.h"가 아니라 "iostream.h"이며 ".h"버전은 더 이상 사용되지 않습니다. 마찬가지로 현대 C++에서는 "string.h"가 아닌 "string"을 사용하고 현대 STL 문자열 클래스를 사용하십시오.
#include <iostream.h>
#include <conio.h>
#include <string.h>
지적한대로이 작업을 수행하지 마십시오. 유형 bool
표준을 다시 정의하여 표준 유형과 반대 값을 갖습니다. 나는 이것이 합법적인지조차 모른다.
enum track {true, false};
main
함수의 리턴 값은 int
하지 void
이다.
void main()
{
clrscr();
버퍼 오버 플로우 란 무엇입니까? 할당 된 메모리가없는 포인터로 str
을 여기에 정의했으며, 나중에 그 정의되지 않은 메모리 비트에 기록합니다. 이것은 정의되지 않은 동작이며 충돌 가능성이 거의 없습니다. 추천 할만한 점은 str
을 std::string
으로 정의해야합니다. 버퍼 오버플로를 방지하고 프로그램에서 사용할 수있는 유용한 메소드가 많이 있습니다.
char*str;
enum track track_pos, track_pos_2;
cout<<"enter the string: ";
여기가 버퍼 오버 플로우입니다. 당신은 누가 어떤 분야의 기억인지 아는 사람에게 편지를 쓰고 있습니다. str
가 std::string
했다
cin>>str;
경우 - 당신은 size_t len=str.length()
할 것;
int len=strlen(str);
cout<<"length of the string is "<<len;
그것은 아마 IOSTREAMS 기능과 같은 콘솔 IO 기능을 혼합하는 것은 좋은 생각이 아니다 - 어려움으로 이어질 수있는 몇 가지 버퍼링 문제가 있습니다. 당신이 다시 사용되지 않기 때문에
getch();
는 루프의 본문에
i
를 선언합니다.과 같이 대신 당신이
i
에서 현재의 문자의 인덱스를 추적하기 때문에 그냥 사용하고 배열로
str
치료, poiter 연산을 사용
for (int i=0; i<len; i++) etc...
int i;
for(i=0;i<len; i++)
{
. 이렇게하면 str
을 i
과 동기화 할 필요가 없습니다. 이것은보고하는 버그의 원인입니다. (즉 str
는 포인터 연산 버전과는 달리 방법에 의한 std::string
경우에도 작동)
if (str[i]=='a' && i%2==0)
:
++str;
cout<<"loop"<<i;
당신은이를 변경해야합니다.
if(*str=='a' && i%2==0)
{
당신은 정말 문자열이 일치하지 않음을 파악하는 경우, 다음 문자열의 끝으로가는 아무 소용이 없다, 어떤 점에서 탈락한다.
cout<<"\nchecking a...";
이 같은 상태 플래그를 선호하지 않는다 - 당신의 코드가 이러한 플래그의 확산, 당신은 적절한 행동을 추적 할 수 없기 때문에 이해하기 위해 부분적으로 단단하다. track_pos
이라는 이름은 니모닉이 아니므로 코드에 대한 세부 연구 없이는 의미가 무엇인지 알아내는 것이 어렵습니다.
for 루프의 본문에있는 코드를 리팩토링하여 함수를 호출하는 것이 좋습니다. 그 목적은 단순히 "ab"그룹 하나와 일치시키는 것입니다.이 함수는 true이면 true를 반환하고, 그렇지 않은 경우 false입니다. 우리가 전에 언급 한 버퍼 오버 플로우를 처리하기 때문에, 당신은 정의되지 않은 메모리를 반복하는 것을
는
track_pos=true;
cout<<"\na.check";
참고. 또한 여기에 i
을 증가시키지 않았 음을 유의하십시오. 우리가 여기에 도착하면
++str;
if (*str=='b')
{
cout<<"\nchecking b...";
track_pos=true;
cout<<"\nb.check";
}
else{
track_pos=false;
cout<<"\nb.uncheck";
}
}
}
은에 따라 루프, 우리는 전체 문자열을 반복했다, 그래서 우리는 (심지어 버퍼 오버 플로우를 무시) 문자열의 끝을지나보고해야합니다 그래서 수있는 방법은 없습니다 이 테스트는 성공할 수 있습니다. 즉, for 루프가 너무 멀리 떨어져 있어야합니다.
if(*str=='b')
track_pos_2=true;
else
track_pos_2=false;
if(track_pos==true && track_pos_2==true)
철자 오류를 언급해야합니까?
cout<<"\nThe string is accpeted.";
else
cout<<"\nThe string is rejected.";
getch();
cout<<"\n\nDo you want to continue (Y/N)? ";
char ch;
cin>>ch;
코드를 적절한 서브 루틴으로 리팩토링하면 프로그램의 구조가 스스로 처리됩니다. main
을 재귀 적으로 호출하는 것은 엄격히 불법은 아니지만 이상하게 보일 수 있으며 프로그램이 종료되지 않는 경우 스택 오버플로가 발생할 수있는 명백한 취약점이 있습니다.
if(ch=='y' || ch=='Y')
main();
}
가 나는 그것이 가장 쉬운 방법 밖으로이었다 main' :-) –
'재귀를 볼 수있는 처음 ... :) – amit
그것은 ++ 그것은 C에서 불법 난독 C 코드 경쟁 항목 –