-1

我正在开发一个将播放文本文件而不是音频或视频的 MediaPlayer 项目。我的问题是如何在 C 字符串数组中显示字符串?例如,如果在我的文本文件中(不带引号):

**"This is only test"**

在我的程序中,我想一次显示一个单词,例如:

This
is
only
test

我怎么做?到目前为止,这是我的代码:

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

//Global variables
int position=0; //to set the player position
float rate = 1.0; //the rate of playback

void LoadFile(const char *fileName, char *text){
    FILE *ifp; //a file pointer for file read/write

    //opening the file
    ifp = fopen(fileName, "r");
    if(ifp == NULL){
            fprintf(stderr, "Can't open input file \"%s\"!\n",fileName);
            exit(1);
    }
    else{
            fgets(text,50,ifp); //getting the text from the file
    }
    //closing the file  
    fclose(ifp); 
}

void *Start();
void *Stop();
void Rewind();
void SeekTo(int byteOffset);
void setRate(float rate);

int main(void){
    int i = 0;
    char choice;
    char fileName[25];
    char lineOfText[50];    //holds the text inside the file
    printf("Please enter the file you want to open: ");
    scanf("%s", fileName);
    LoadFile(fileName,lineOfText);
    printf("%s",lineOfText);   //I will display the whole string

    return 0;
}
4

5 回答 5

1

使用 strtok 函数

#include < stdio.h >

#include < string.h >

int main ()
{
  char str[] ="- This, a sample string.";
  char * pch;
  //printf ("Splitting string \"%s\" into tokens:\n",str);
  pch = strtok (str," ,.-");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ,.-");
  }
  return 0;
}

此代码将给出输出

This
a
sample
string

为了进一步了解,请转到以下内容

http://www.cplusplus.com/reference/clibrary/cstring/strtok

于 2012-06-01T19:59:43.193 回答
1

由于您使用的是 C++,因此您可以使用Boost轻松做到这一点。从文件中读取该行后,您可以构造 astring然后使用boost::split

string line(text);
vector<string> words;
split(words, line, is_any_of(" "));

之后,您可以迭代vector获取从文件中读取的单个单词。例如,对于顺序打印所有单词(使用 C++11 语法):

for (const auto& w : words)
    cout << w << endl;

此外,您可能还想考虑将您的程序移植到真正的C++。为此,您需要使用string而不是char数组,ifstream用于读取文件等。

于 2012-06-01T19:44:51.267 回答
0

可能重新发明轮子,但有时非常有用:

// substring_container_adapter.h
//
// substring_container_adapter is useful for treating a single master string as a collection of substrings
// for the purpose of enumerating over those substrings (read-only)
//
// NOTES:
//  (1) sequential forward access is reasonably efficient, but random access is definitely not very efficient.  (bidirectional could be implemented)
//  (2) the strings must be valid for the lifetime of the adapter and any enumerators you obtain from the adapter
//  (3) uses a greedy algorithm - so whole sequences of delimiters are considered one separator, rather than multiple separators

namespace details 
{
    template <typename charT>
    class substring_container_adapter
    {
    public:
        struct iterator : public std::iterator<std::forward_iterator_tag, const charT *>
        {
            // iterator constructor
            iterator(const charT * pszPosition, const charT * pszDelimeters)
                : m_pszPosition(pszPosition)
                , m_pszDelimeters(pszDelimeters)
                , m_pszEnd(FindOneOfOrNil(pszPosition, pszDelimeters))
            { }

            // supported relational operators
            bool operator == (const iterator & rhs) const { return m_pszPosition == rhs.m_pszPosition; }
            bool operator != (const iterator & rhs) const { return m_pszPosition != rhs.m_pszPosition; }
            bool operator <  (const iterator & rhs) const { return m_pszPosition < rhs.m_pszPosition; }

            // increment to next substring
            iterator & operator ++ ()
            {
                const charT * pszNext = SkipDelimeters(m_pszEnd, m_pszDelimeters);
                if (pszNext)
                {
                    m_pszPosition = pszNext;
                    m_pszEnd = FindOneOfOrNil(m_pszPosition, m_pszDelimeters);
                }
                else
                {
                    m_pszPosition += GetLength(m_pszPosition);
                }

                return *this;
            }

            // postfix increment
            const iterator operator ++ (int)
            {
                // note: the const return type flags misuse patterns (see More Effective C++, Item 6)
                iterator old(*this);
                ++(*this);
                return old;
            }

            // dereference == CString
            CString operator * () const { return CString(m_pszPosition, static_cast<int>(m_pszEnd - m_pszPosition)); }

            // iterators on our characters
            const charT * begin() const { return m_pszPosition; }
            const charT * end() const { return m_pszEnd; }

        private:

            const charT *   m_pszPosition;
            const charT *   m_pszDelimeters;
            const charT *   m_pszEnd;
        };

        typedef iterator const_iterator;

    public:
        substring_container_adapter(const charT * pszString, const charT * pszDelimeters)
            : m_pszString(pszString)
            , m_pszDelimiters(pszDelimeters)
            , m_end(pszString + GetLength(pszString), m_pszDelimiters)
          { }

          // iterators
          iterator begin() const { return iterator(m_pszString, m_pszDelimiters); };
          iterator end()  const { return m_end; };

    private:
        const charT *   m_pszString;        // zero-terminated character array
        const charT *   m_pszDelimiters;    // delimiters
        const iterator  m_end;              // end delimiter
    };

}

typedef details::substring_container_adapter<TCHAR> substring_container_adapter;
于 2012-06-01T19:50:49.373 回答
0

您收到错误的原因:

printf("%s",lineOfText[0]);

是char使用了不同的标志。你需要:

printf("%c",lineOfText[0]);

那只会在 c 字符串中打印字符。只需遍历数组即可访问剩余的字符。

于 2012-06-01T19:51:53.513 回答
0

这里有一个简单的提示,

  • 取两个变量。用 0 初始化它们。
  • 开始遍历字符串。
  • 如果你找到一个空格,记下它的索引到第二个变量中。
  • 将声明的第一个变量到第二个变量的内容复制到字符串中。
  • 使第一个变量=第二个变量。

继续执行上述步骤,直到字符串结束。

于 2012-06-01T22:58:23.347 回答