2010-07-09 39 views
36

Ngay bây giờ tôi đang cố gắng này:Làm thế nào để lặp qua một chuỗi trong C?

#include <stdio.h> 

int main(int argc, char *argv[]) { 

    if (argc != 3) { 

     printf("Usage: %s %s sourcecode input", argv[0], argv[1]); 
    } 
    else { 
     char source[] = "This is an example."; 
     int i; 

     for (i = 0; i < sizeof(source); i++) { 

      printf("%c", source[i]); 
     } 
    } 

    getchar(); 

    return 0; 
} 

này cũng không làm việc:

char *source = "This is an example."; 
int i; 

for (i = 0; i < strlen(source); i++){ 

    printf("%c", source[i]); 
} 

tôi nhận được lỗi

Unhandled ngoại lệ tại 0x5bf714cf (msvcr100d.dll) trong Test.exe: 0xC0000005: Truy cập vi phạm khi đọc ở vị trí 0x00000054.

(lỏng lẻo dịch từ tiếng Đức)

Vì vậy, có gì sai với mã của tôi?

+3

vui lòng không chỉnh sửa mã mà bạn đã hỏi. Điều đó thay đổi câu hỏi của bạn khá nhiều để nhiều câu trả lời không liên quan. Thay vào đó, chỉ cần đăng tất cả những điều bạn đã thử và đề cập đến câu trả lời nào trong số đó. –

+0

Thử nghiệm mới đối với argc bạn đã thêm sai. –

Trả lời

41

Bạn muốn:

for (i = 0; i < strlen(source); i++){ 

sizeof cho bạn biết kích thước của con trỏ, không phải là chuỗi. Tuy nhiên, nó sẽ hoạt động nếu bạn đã khai báo con trỏ dưới dạng một mảng:

char source[] = "This is an example."; 

nhưng nếu bạn chuyển mảng để hoạt động, quá cũng sẽ phân rã thành con trỏ. Đối với chuỗi tốt nhất là luôn luôn sử dụng strlen. Và lưu ý những gì người khác đã nói về việc thay đổi printf để sử dụng% c. Và cũng có thể, lấy mmyers ý kiến ​​về hiệu quả vào tài khoản, nó sẽ là tốt hơn để di chuyển các cuộc gọi đến strlen ra khỏi vòng lặp:

int len = strlen(source); 
for (i = 0; i < len; i++){ 

hoặc viết lại vòng lặp:

for (i = 0; source[i] != 0; i++){ 
+2

Uh, tôi nghi ngờ anh ta muốn sử dụng 'strlen' như một ràng buộc. (Mặc dù được cấp, trong một chương trình 10 dòng nó không tạo ra nhiều khác biệt.) –

+1

@mmyers Um, tại sao không? –

+9

Vâng, cuối cùng tôi đã kiểm tra, strlen đã phải lặp qua tất cả các ký tự để tìm ra độ dài. Và vì char * có thể thay đổi trong vòng lặp, các strlen không thể được treo ra khỏi giới hạn kiểm tra bởi trình biên dịch; làm cho vòng lặp O (n^2) thay vì O (n). Nêu tôi sai vui long chân chỉnh tôi. –

0

Chỉ cần thay đổi sizeof bằng strlen.

Như thế này:

char *source = "This is an example."; 
int i; 

for (i = 0; i < strlen(source); i++){ 

    printf("%c", source[i]); 

} 
+0

mã này sẽ vẫn có ngoại lệ vì% s và char được chuyển tới printf – ULysses

+0

Cảm ơn bạn đã chỉ ra điều đó. –

2

sizeof(source) trả về số byte được yêu cầu bởi con trỏ char*. Bạn nên thay thế nó bằng strlen(source) sẽ là độ dài của chuỗi bạn đang cố gắng hiển thị.

Ngoài ra, bạn có thể nên thay thế printf("%s",source[i]) bằng printf("%c",source[i]) vì bạn đang hiển thị ký tự.

+0

sau đó ... có khả năng 'printf ("% c ", nguồn [i])' với 'putchar (nguồn [i])' ... – ShinTakezou

0

Thay thế sizeof bằng strlen và nó sẽ hoạt động.

0

Bạn cần một con trỏ tới char đầu tiên để có chuỗi ANSI.

printf("%s", source + i); 

sẽ làm công việc

Thêm vào đó, tất nhiên bạn nên có nghĩa strlen(source), không sizeof(source).

1

này nên làm việc

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

int main(int argc, char *argv[]){ 

    char *source = "This is an example."; 
    int length = (int)strlen(source); //sizeof(source)=sizeof(char *) = 4 on a 32 bit implementation 
    for (int i = 0; i < length; i++) 
    { 

     printf("%c", source[i]); 

    } 


} 
1
  • sizeof(source) đang trở lại để bạn biết kích thước của một char*, không phải là chiều dài của chuỗi.Bạn nên sử dụng strlen(source) và bạn nên di chuyển nó ra khỏi vòng lặp, nếu không bạn sẽ tính toán lại kích thước của chuỗi mỗi vòng lặp.
  • Bằng cách in với công cụ sửa đổi định dạng %s, printf đang tìm kiếm char*, nhưng bạn thực sự đang chuyển một số char. Bạn nên sử dụng công cụ sửa đổi %c.
2
  1. sizeof() bao gồm ký tự null kết thúc. Bạn nên sử dụng strlen() (nhưng đặt cuộc gọi bên ngoài vòng lặp và lưu nó trong một biến), nhưng đó có lẽ không phải là những gì gây ra ngoại lệ.
  2. bạn nên sử dụng "% c", không phải "% s" trong printf - bạn đang in một ký tự chứ không phải chuỗi.
31

Một thành ngữ phổ biến là:

char* c = source; 
while (*c) putchar(*c++); 

Một vài lưu ý:

  • Trong C, chuỗi là null-terminated. Bạn lặp lại trong khi ký tự đọc không phải là ký tự null.
  • *c++ gia số c và trả lại số đăng ký cũ bị hủy đăng ký cũ của c.
  • printf("%s") in chuỗi bị chấm dứt không có giá trị, không phải là ký tự đại diện. Đây là nguyên nhân dẫn đến vi phạm quyền truy cập của bạn.
+1

Tôi có thể sử dụng 'while (* C++) putc (* c);' ? –

+0

-1 "Trong C, chuỗi không được chấm dứt." Điều này không có ý nghĩa. Có lẽ những gì bạn đang cố gắng để nói là c-strings nên được null chấm dứt. – Celeritas

+3

@Celeritas: Tôi thấy downvote hơi khắc nghiệt - C có hỗ trợ ngôn ngữ cho các chuỗi không bị chấm dứt, và OP đang sử dụng chúng. Cấp, bạn có thể sử dụng chuỗi tính (ví dụ. 'BSTR' trong thế giới cửa sổ), nhưng chúng ít phổ biến hơn, và câu hỏi không rõ ràng là loại chuỗi nào đang sử dụng. –

2

Thay vì sử dụng strlen như đề xuất ở trên, bạn chỉ có thể kiểm tra các nhân vật NULL:

#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    const char *const pszSource = "This is an example."; 
    const char *pszChar = pszSource; 

    while (pszChar != NULL && *pszChar != '\0') 
    { 
     printf("%s", *pszChar); 
     ++pszChar; 
    } 

    getchar(); 

    return 0; 
} 
+1

Nó sẽ hoạt động, nhưng tôi khuyên bạn nên kiểm tra 'pszChar! = '\ 0'' để được rõ ràng anyways. Bạn không so sánh với 'NULL' (thường cho con trỏ), nhưng đối với ký tự null, kết thúc chuỗi C. (Ngoài ra, cả hai đều bằng 0, do đó, 'pszChar && * pszChar' cũng là một điều kiện tốt, nếu bạn đang ở trong loại điều đó). –

0

sizeof(source) lợi nhuận sizeof một con trỏ như là nguồn được khai báo là char *. Cách đúng để sử dụng nó là strlen(source).

Tiếp theo:

printf("%s",source[i]); 

hy vọng chuỗi. tức là% s mong đợi chuỗi nhưng bạn đang lặp trong một vòng lặp để in từng ký tự. Do đó sử dụng% c.

Tuy nhiên cách truy cập của bạn (lặp lại) một chuỗi bằng chỉ mục i là chính xác và do đó không có vấn đề nào khác trong đó.

Các vấn đề liên quan