의견이 있으십니까?
네, 상당수.
먼저 오류가 발생하여 직접 해결할 수없고 도움을 청하기로 결정한 경우 문제를 재현하는 코드를 게시하십시오. 오류가 어디에서 발생하는지 파악할 수 없으면 프로그램의 어느 부분이 오류와 관련이 있고 그렇지 않은 부분이 올바른지 결정할 수 없습니다. 내 평소 접근 방식은 오류가 다시 나타날 때까지 새 파일로 시작하고 코드를 추가하는 것입니다. 필자는 복사 및 붙여 넣기를 피하면서 다시 타이핑하기를 바보로 오타를 복제하지 않기 때문에 붙여 넣기를 권장합니다. 종종 최소한의 작업 (또는 실패한 경우) 예제를 작성하여 문제를 직접 해결하는 방법을 배우게됩니다. 당신의 질문과 관련이 없다면 당신의 예제에서 비표준 의존성을 피하십시오. 귀하의 예에서는 clrscr
기능을 제거해야합니다. 또한 코드를 읽을 수있는 형식으로 포맷팅하는 데 2 분의 시간을 더 걸리는 것이 좋습니다.
코드 작성 : 나는 최소한의 실용 예제를 만들었습니다.
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <iostream>
struct pharmacy_personnel
{
pharmacy_personnel(const char *const name_of_medicine = "Tonic Water")
{
std::strncpy(this->name_of_medicine_, name_of_medicine, 50);
this->name_of_medicine_[49] = '\0';
}
const char *
get_name_of_medicine() const
{
return this->name_of_medicine_;
}
private:
char name_of_medicine_[50];
};
int
main()
{
const std::size_t total = 10;
char name[50];
//clrscr();
std::cout << "Please enter the name of the medicine: ";
std::cin >> name;
pharmacy_personnel * ob2 = new pharmacy_personnel[total];
for (std::size_t i = 0; i < total; ++i)
{
if(std::strcmp(name, ob2[i].get_name_of_medicine()) == 0)
{
std::cout << "Yes, we have that medicine.\n";
return EXIT_SUCCESS;
}
}
std::cout << "Sorry, we don't have that medicine.\n";
return EXIT_FAILURE;
}
"갑자기"오류없이 컴파일됩니다. 이는 원래 질문에 관련 정보가 누락되었음을 나타냅니다. 내 최선의 방법은 pharmacy_presonnel::get_name_of_medicine()
의 구현이 const char *
을 반환해야 할 때 char
을 반환한다는 것입니다.
하지만이 코드에는 정말 고쳐야 할 사항이 많이 있습니다.
첫 번째 놀라운 수 있습니다이 하나
$ ./a.out
Please enter the name of the medicine: Tonic Water
Sorry, we don't have that medicine.
아마 두 번째이 하나 (공격자가 수행하기 전에 당신이 그것을 발견 할 희망) :
$ ./a.out
Please enter the name of the medicine: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Segmentation fault
두 문제는 C를 사용하지 않는 사용자로부터 발생 ++ 기술이지만 안전하지 못한 저수준 C 스타일 I/O. 그들은 확실히 C 스타일 프로그래밍으로 고정 될 수 있지만, 왜 C++을 전혀 사용하지 않는가?
C++에서 우리는 보통 std::string
클래스에 문자열을 저장합니다. 이 클래스는 문자열에 충분한 크기의 버퍼를 할당하고 객체가 범위를 벗어날 때이를 할당 해제합니다. 그런 다음 실제로는 pharmacy_personnel
클래스에서 C++ 문자열을 사용해야합니다.
std::string
에 대한 또 다른 좋은 점은 연산자 ==
을 사용하여 간단히 비교할 수 있다는 것입니다. 이로 인해 cstring
헤더가 중복됩니다.
일반 "입력 연산자">>
은 공백으로 멈 춥니 다. 의약품의 이름에는 빈칸이있을 가능성이 높기 때문에 std::getline
함수를 사용하여 전체 입력란을 읽는 것이 좋습니다. 우리가 얻을 모든 적용
:
#include <cstddef>
#include <cstdlib>
#include <iostream>
#include <string> // This is the C++, not the C header!
struct pharmacy_personnel
{
pharmacy_personnel(const std::string& name_of_medicine = "Tonic Water")
: name_of_medicine_(name_of_medicine)
{
}
std::string
get_name_of_medicine() const
{
return this->name_of_medicine_;
}
private:
std::string name_of_medicine_;
};
int
main()
{
const std::size_t total = 10;
std::string name;
std::cout << "Please enter the name of the medicine: ";
std::getline(std::cin, name);
pharmacy_personnel * ob2 = new pharmacy_personnel[total];
for (std::size_t i = 0; i < total; ++i)
{
if(name == ob2[i].get_name_of_medicine())
{
std::cout << "Yes, we have that medicine.\n";
return EXIT_SUCCESS;
}
}
std::cout << "Sorry, we don't have that medicine.\n";
return EXIT_FAILURE;
}
이는 문자열 관련 문제를 해결하지만 다른 사람들이 여전히있다. 나는 name
을 total
동일한 문자열과 비교하는 목적이 "벗은"운영자의 것이어야한다고 확신하지는 않습니다. new
은 거의 확실하게 나쁜 생각입니다. (지금까지 게시 된 프로그램은 바로 그 이유 때문에 메모리 누출이 있습니다.) C++의 std::vector
으로 업그레이드 할 것입니다.
// Other headers as before.
#include <vector> // for std::vector
// No changes to struct pharmacy_personnel.
int
main()
{
const std::size_t total = 10;
std::string name;
std::cout << "Please enter the name of the medicine: ";
std::getline(std::cin, name);
std::vector<pharmacy_personnel> ob2(total);
for (std::size_t i = 0; i < ob2.size(); ++i)
{
if(name == ob2[i].get_name_of_medicine())
{
std::cout << "Yes, we have that medicine.\n";
return EXIT_SUCCESS;
}
}
std::cout << "Sorry, we don't have that medicine.\n";
return EXIT_FAILURE;
}
이미 C++ (11)를 사용하는 경우, 우리는 코드가 더 많은 표현 (오류가 발생하기 쉬운 이하) 루프 범위-에 대한 사용하여 만들 수 있습니다. 이렇게하면 벡터 요소에 명시 적으로 번호를 매길 필요가 없습니다. (반복자를 사용하여, 나는이 반복자를 사용하여 수동으로 더 읽기 코드를 만드는 것을 발견 적이 없다. 당신은 C++ 98 중 하나에 그렇게 할 필요는 없지만, 새로운 구문이 훨씬 청소기입니다.)
for (const auto& iter : ob2)
{
if(name == iter.get_name_of_medicine())
{
std::cout << "Yes, we have that medicine.\n";
return EXIT_SUCCESS;
}
}
마지막 일을 내가 언급 할 수 있듯이 네이밍 및 클래스 디자인이 향상 될 수 있습니다. ob2
이름은 무엇을 말해야합니까? 더 중요한 이유 : 클래스 pharmacy_personnel
(직원을 대변하기로되어 있습니까?)과 관련된 약의 이름이있는 이유는 무엇입니까? 모든 직원이 정확히 하나의 약에 대한 책임이 있지만 이상하게 들릴 경우 결국에는 의미가 있습니다. 이상적으로, 클래스는 도메인 (즉, 실제)을 최대한 가깝게 모델링합니다. 그렇게하기 위해 코드를보다 체계적으로 구성하고 이해하기 쉬우 며 따라서 유지 관리가 쉬우 며 코드를 만드는 것이 더 중요합니다.
-1 내 첫 번째 제안은 들여 쓰기를 수정하는 것입니다. – kay
컴파일러 오류 중 어느 부분이 불분명합니까? 그건 그렇고, 말도 안되는 제한이 없다면 C++이 어떻게 쓰여지는 것은 아닙니다. – chris
'strcmp'는'const char *'타입의 두 개의 인수를 받아들입니다. –