输出不如预期

时间:2017-02-24 00:08:41

标签: c string pointers for-loop output

我应该编写一个程序来提取以www.开头并以.edu结尾的网址。程序显示用户输入的输入中包含的Web地址。如果输入不包含以www.开头且以.edu结尾的网址,则程序应显示一条消息,指示无法找到此类网址。

Input: http://www.usf.edu/admission
Output: www.usf.edu
Input: https://www.facebook.com/
Output: Web address starting with www. and ending with .edu not found

然而,当我的程序运行时,它没有显示正确的输出。我没有任何编译错误或警告,所以我不确定问题出在哪里。

// This program extracts the text from the website URL
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define STR_LEN 1000

void read_line(char *str, int n);
void pass_check(char *str);
void extract(char *s1, char *s2);

int main(void)
{
    char instr[STR_LEN + 1];
    char outstr[STR_LEN + 1];

    printf("Please enter a URL: ");
    read_line(instr, STR_LEN);
    extract(instr, outstr);

    puts(outstr);
    pass_check(outstr);

    return 0;
}

void extract(char *s1, char *s2) {
    char *p, *q;
    q = s2;
    for (p = s1 + 7; *p != 0; p++) {
        if (*p == '/')
            break;
        else {
            *q = *p;
            q++;
        }
    }
    *q = '\0';
    *p = '\0';
}

void read_line(char *str, int n) {
    int ch;
    int i = 0;
    while ((ch = getchar()) != '\n') {
        if (i < n) {
            *str++ = ch;
            i++;
        }
    }
    *str = '\0';
}

void pass_check(char *str) {
    const char *fref = "www";
    const char *lref = "edu";

    int len = strlen(str);
    printf("%d", len);

    char *l = &str[len - 3];
    char f[STR_LEN + 1];

    strncpy(f, str, 3);

    if ((strcmp(f, fref) == 0) && strcmp(l, lref) == 0) {
        printf("Output: ");
        puts(str);
        printf("\n");
    } else
        printf("Please only insert a .edu URL.");
}

1 个答案:

答案 0 :(得分:1)

函数strncpy()没有按照您的想法执行:strncpy(f, str, 3);不会向f追加空字节,因此strcmp(f, fref);实际上会有f未定义的行为{ {1}}在前3个字节之外未初始化。

请勿使用此功能,请从以下博客中了解原因:

另请注意,readline()函数将运行无限循环,文件为空或未被换行终止。

以下是更正后的版本:

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

#define STR_LEN 1000

void read_line(char *str, size_t n);
int extract(const char *str, char *dest);

int main(void) {
    char instr[STR_LEN + 1];
    char outstr[STR_LEN + 1];

    printf("Please enter a URL: ");
    read_line(instr, sizeof(instr));
    if (extract(instr, outstr)) {
        puts(outstr);
    } else {
        printf("Web address starting with www. and ending with .edu not found\n");
    }
    return 0;
}

int read_line(char *str, size size) {
    int ch;
    size_t i = 0;
    while ((ch = getchar()) != EOF && c != '\n') {
        if (i + 1 < size) {
            str[i++] = ch;
        }
    }
    str[i] = '\0';
    return (ch == EOF && i == 0) ? EOF : i;
}

int extact(const char *str, char *dest) {
    const char *p;

    *dest = '\0';

    for (;;) {
        if ((p = strstr(str, "https://www.")) != NULL) {
            p += 8;  // skip the https:// prefix
        } else 
        if ((p = strstr(str, "http://www.")) != NULL) {
            p += 7;  // skip the http:// prefix
        } else {
            break;
        }
        // URL starts with www.
        size_t len = strcspn(p, "/ \n");  // compute length of website name
        if (len > 8 && !memcmp(p + len - 4, ".edu", 4)) {
            // copy website name, assuming dest is at least as large as str
            strncat(dest, p, len);
            return 1;
        }
        str = p + len;
    }
    return 0;
}