Vì lý do đào tạo, tôi muốn lập trình một chiếc máy tính nhỏ. Tại sao chúng ta tính 10-6 = 16 thay vì 10-6 = 4?
Tôi đã gặp lỗi:
Khẳng định không thành công!
Biểu thức: calc("10-6") == 4 && "không thể thực hiện phép trừ"
đây là mã của tôi
#include
#include
#include
#include
#include
#include
calc kép (đầu vào char *);
trích xuất kép_first_integer(char * input);
trích xuất kép_last_integer(char * input);
char extract_operand(char * đầu vào);
int main()
{
khẳng định (calc ("10-6") == 4 && "không thể thực hiện phép trừ");
return 0;
}
gấp đôi calc(char *input){
gấp đôi num1 = extract_first_integer(input);
gấp đôi num2 = extract_last_integer(input);
char toán hạng = extract_operand(input);
printf("toán hạng là %c\n", toán hạng);
chuyển đổi (toán hạng)
{
trường hợp '-':
printf("num1 - num2: %f\n", num1-num2); // đầu ra: 16 thay vì 4
trả về số1 - số2;
phá vỡ;
}
}
trích xuất kép_first_integer(char * input){
char *str = đầu vào, *p = str;
giá trị đôi;
while (*p) { // Trong khi có nhiều ký tự hơn để xử lý...
if ( isdigit(*p) || ( (*p=='-'||*p=='+') && isdigit(*(p+1)) )) {
// Tìm thấy một số
val = strtol(p, &p, 10); // Đọc số
trả lại giá trị;
} khác {
// Nếu không thì chuyển sang ký tự tiếp theo.
p++;
}
}
}
trích xuất kép_last_integer(char * input){
char *str = đầu vào, *p = str;
giá trị đôi;
while (*p) { // Trong khi có nhiều ký tự hơn để xử lý...
if ( isdigit(*p) || ( (*p=='-'||*p=='+') && isdigit(*(p+1)) )) {
// Tìm thấy một số
val = strtol(p, &p, 10); // Đọc số
} khác {
// Nếu không thì chuyển sang ký tự tiếp theo.
p++;
}
}
trả lại giá trị;
}
char extract_operand(char * input){
if (strstr(input, "-")) return '-';
}
hiện hữu extract_last_integer()
bạn có
while (*p) { // Trong khi có nhiều ký tự hơn để xử lý...
if ( isdigit(*p) || ( (*p=='-'||*p=='+') && isdigit(*(p+1)) )) {
// Tìm thấy một số
val = strtol(p, &p, 10); // Đọc số
} khác {
// Nếu không thì chuyển sang ký tự tiếp theo.
p++;
}
}
Tăng P
cho đến khi gặp số đầu tiên hoặc -
/+
theo sau là một con số. vì vậy nó sẽ phù hợp第一个10
con số. Nhưng xin lưu ý rằng bạnkhông thích extract_first_integer()
sớm vào trả lại giá trị;
Điều đó phá vỡ chu kỳ. Khi bạn tiếp tục khớp số tiếp theo,"10-6"
TRONG -6
sẽ được khớp. Và 10 - (-6)
Rõ ràng là 16
Bạn cũng có thể có hành vi không xác định
- Truyền con trỏ tương tự tới
strtol
. biến str
Chưa sử dụng nên đổi thành str_end
được truyền vào tham số
- Sẽ
const char*
("10-6"
) đã được chuyển đến nhu cầu char*
chức năng
3trích xuất...
Các hàm cũng hoạt động không tốt vì chúng đều yêu cầu lặp lại từ đầu chuỗi đầu vào. Để giải quyết vấn đề này bạn nên trả về vị trí của số hiện tại và bắt đầu hàm tiếp theo từ vị trí đó. Bằng cách này bạn có thể sử dụng hàm tương tự để phân tích các số nguyên thay vì viết hai
Ngoài ra, tên của bạn bị lộn ngược. Hai số nguyên này được gọi là toán hạngThứ kết nối hai toán hạng được gọi là toán tử , không phải là toán hạng. Tại sao nó được trả về khi chỉ đọc số nguyên? gấp đôi
?
Vì vậy sau khi sửa những điểm này chúng ta sẽ có
int extract_operand(char * input, size_t *lastChar);
char extract_operator(char * input, size_t *lastChar);
size_t cuối cùngPos;
int num1 = extract_operand(input, &lastPos);
char toán hạng = extract_operator(input + LastPos, &lastPos);
int num2 = extract_operand(input + LastPos, &lastPos);
Nhưng điều này chỉ hoạt động với toán tử nhị phân Trường hợp đơn giản của và 2 toán hạng như vậy. Đối với những trường hợp phức tạp hơn bạn cần mã thông báoChia luồng đầu vào thành danh sách mã thông báo
Tôi là một lập trình viên xuất sắc, rất giỏi!