计算c字符串中的单词

时间:2013-12-01 21:30:49

标签: c++ cstring

我需要帮助才能完成此功能,以便正确返回c-string中的单词数。也许我的逻辑错了?

#include <iostream>
#include <string>
#include <cctype>
int countwords(char *, int);
using namespace std;

int main()
{
    char a[] = "Four score and seven";
    int size = sizeof(a)/sizeof(char);
    cout << countwords(a,size);

    return 0;
}

int countwords(char* a, int size){
    int j = 0;
    for(int i = 0; i < size; i++){
        if(isspace(i) and isalnum(i - 1) and isalnum(i + 1))
            j++;
    }

    return j;
}

4 个答案:

答案 0 :(得分:2)

您将i的值传递给这些函数而不是a[i]。这意味着您正在测试循环变量是否为空格(例如),而不是a数组中该位置的字符。

修复后,请了解您不能盲目地在该循环中引用a[i-1](因为有可能访问a[-1]。您需要更新逻辑(请注意,您必须使用&&表示逻辑AND,而不是and)。

我建议使用一个标志来表明你当前是否在“内部”一个单词。每当你决定不再在单词中时,重置该标志。 例如

int inside = 0;
for (int i = 0; i < size; i++) {
    if (alnum(a[i])) {
        if (!inside) {
            inside = 1;
            j++;
        }
    } else {
        inside = 0;
    }
}

另外,请使用strlen(a)代替sizeof(a)/sizeof(char)。如果你继续这种练习,那么当你在指针上尝试它时,你一定会发生意外。

答案 1 :(得分:0)

此循环无效

for(int i = 0; i < size; i++){
    if(isspace(i) and isalnum(i - 1) and isalnum(i + 1))

首先,您不检查字符串的字符,无论它们是空格还是字母数字。你检查变量i whicj与字符串的内容没有什么共同之处。此外,您有意访问数组之外​​的内存

在处理字符串时,我会按以下方式声明函数

size_t countwords( const char *s );

可以定义为

size_t countwords( const char *s )
{
    size_t count = 0;

    while ( *s )
    {
        while ( isspace( *s ) ++s;
        if ( *s ) ++count;
        wjile ( isalnum( *s ) ++s;
    }

    return ( count );
}

我没有考虑标点符号。否则你应该用isspace替换!isalnum。

答案 2 :(得分:0)

更简单的版本是在字符串上重复调用strtok(),每次返回一个元素时,都可以增加字数。这会占用双倍的空间,等等。你甚至可以用逗号分割两个单词但没有空格(“this,error”)没有任何困难。

类似于:

do {
  s = strtok(s," ,.;");
  if (s) wordcount++;
 } while(s);

唯一的直接缺点是strtok是破坏性的,所以在开始之前制作副本。

答案 3 :(得分:0)

要计算单词数,您只需计算在空白字符后看到非空白字符的次数。为了在字符串的开头处把事情做好,假设字符串左边有“空格”。

int countwords(char* a, int size) {
    bool prev_ws = true;  // pretend like there's whitespace to the left of a[]
    int words = 0;

    for (int i = 0; i < size; i++) {
        // Is the current character whitespace?
        bool curr_ws = isspace( (unsigned char)a[i] ); 

        // If the current character is not whitespace, 
        // but the previous was, it's the start of a word.
        if (prev_ws && !curr_ws) 
            words++;

        // Remember whether the current character was 
        // whitespace for the next iteration.
        prev_ws = curr_ws;
    }

    return words;
}

您可能还会注意到我在调用unsigned char时向isspace()添加了演员。在某些平台上,char默认为已签名,但分类器函数isspace和朋友不能保证使用负值。演员强迫所有的价值观都是积极的。 (更多细节:http://en.cppreference.com/w/cpp/string/byte/isspace