2016-12-11 40 views
1

以下は、コードブロックバージョン13:12の私のコードです。私は髪を紛失してここに尋ねるのを素早く断念したので、コメントはしていません!私の懸念は、自分のchar *ターゲットが/cat.html?name=imageになると予想しているが、私は/cat.htmlしか得られないということだ!これらの行の後なぜstrtok()は '?'を選択しないのですか?行からのキャラクター?

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

int main() { 
    const char *space = " "; 
    const char *marker = "?"; 
    const char line[] = { "GET /cat.html?name=image HTTP/1.1" }; 
    int n = strlen(line), i, j, k, a; 
    char string[n + 1]; 

    for (i = 0; i <= n; i++) { 
     string[i] = line[i]; 
     string[n] = '\0'; 
    } 
    printf(" line has %i characters \n\n", n); 
    char *method = strtok(string, space); 
    char *target = strtok(NULL, space); 
    char *version = strtok(NULL, space); 

    char *abs_path = strtok(target, marker); 
    char *query = strtok(NULL, marker); 

    printf("\n line is:%s \n" 
      "\n method is:%s \n" 
      "\n target is:%s \n" 
      "\n version  is:%s \n" 
      "\n abs_path is:%s \n" 
      "\n query is:%s \n\n\n", 
      line, method, target, version, abs_path, query); 

    int l = strlen(target); 
    if (strcmp(method, "GET") != 0) { 
     printf("wrong method error 405 \n\n"); 
    } 

    printf(" target contains %i characters \n\n", l); 
    for (j = 0; j <= l; j++) { 
     if (target[0] != '/') { 
      printf("wrong target does not start with \\/error 501\n\n"); 
     } 
     if (target[j] == '"') { 
      printf("wrong target error 400 has a \" \n\n"); 
     } 
    } 
    if (strchr(abs_path, '.') == NULL) { 
     printf("wrong absolute path has no \. \n\n"); 
    } 
    if (strncmp(version, "HTTP/1.1", 8) != 0) { 
     printf("wrong version not HTTP/1.1 error 505 \n\n"); 
    } 
    return 0; 
} 
+0

あなたのコードは、 'const char line [] =" ... ";'が与えられているので、火で再生されています。 'line [4] = line [4];'を書くと、定数配列を変更することができないので、コンパイラはあなたを妨害します。しかし、その配列を 'strtok()'に渡します。これは、配列上のさまざまな点にヌルを書き込んで配列全体を渡ります。それは動作することが保証されていません。 'line'の定義から' const'を削除してください。 –

答えて

2

strtok()は、最初の引数に渡されたバッファを変更します。最初の3回の呼び出しの後に、method,targetおよびversionのいずれかがNULLであるか、またはstringの配列が第1、第2および第3のスペースで区切られた部分に対応するフラグメントになります。

char *method = strtok(string, space); 
char *target = strtok(NULL, space); 
char *version = strtok(NULL, space); 

methodstring+0"GET"string[3]string+4"/cat.html?name=image"'\0'
target点に設定されている、string[24]'\0'に設定されています。
version"HTTP/1.1"を指し、string+25を指す。あなたはtargetstrtokへのさらなる呼び出しを発行すると

string配列が変更されると?'\0'で上書きされます。

char *abs_path = strtok(target, marker); 
char *query = strtok(NULL, marker); 
abs_path

string+4"/cat.html"に、string[13]'\0'はに設定されています。
queryを指し、"name=image"string+14とする。

あなたは文字列がtargetで指さ保存したい場合は、はstrtok() `へのコールの第二のセットの前にコピーを作成する必要があります。

char *saved_target = strdup(target); 
char *abs_path = strtok(target, marker); 
char *query = strtok(NULL, marker); 

そしてprintfでそれを使用します。

printf("\n line is:%s \n" 
      "\n method is:%s \n" 
      "\n target is:%s \n" 
      "\n version  is:%s \n" 
      "\n abs_path is:%s \n" 
      "\n query is:%s \n\n\n", 
      line, method, saved_target, version, abs_path, query); 
+0

ありがとう@chqrlie。あなたはそれをさらに明確にしました。私はstrdup()を使用せずに手動でコピーを作成しようとしています。私はC言語を学んでいると見ています。もう一度ありがとう、それはうまくいった。 –

+0

ちょうどそうでした、ありがとう。 –

3
char * method = strtok(string, space); 
char * target = strtok(NULL, space); 
char * version = strtok(NULL, space); 

targetは確かに価値"/cat.html?name=image"を持っています。あなたはtargetの元の値を保持したい場合はtargetは、その値に"/cat.html"

を持つことになり、その行の後

abs_path = strtok(target, marker); 

:問題は、その文字列を変更しますどのtargetで再度のstrtokを呼び出すことです第2のstrtokの前にそれをコピーする必要があります。 on target

+0

多くの感謝と私に助けをした@ kaylumをありがとう。私は、abs_pathのためにstrtok()を呼び出している間中断していなければならないことがわかります。 –

関連する問題