如何在C中将一个字符变成一个单词
how to make a char into one word in C
我目前正在从一个文件中收集输入,但我的程序将每个字母而不是每个单词分隔到 char 数组中。如何更改我的代码以获取每个单词?
char c, fileName[20];
FILE *f;
void getFile() {
f = fopen(fileName, "r");
while((c = fgetc(f)) != EOF) {
printf("%c",c);
}
fclose(f);
}
改用fscanf(3)
char word[256], *p;
while(fscanf(f, "%s", &word) != EOF) {
printf("%s\n", word);
/* break down word into individual chars */
for(p=word; *p; p++) {
printf("%c ", *p);
}
printf("\n");
}
你可以使用 char * fgets ( char * str, int num, FILE * stream );
然后使用 char *strtok(char *str, const char *delim)
例如
#include <stdio.h>
int main()
{
FILE * pFile;
char mystring [100];
const char delimters[2] = " ,:";
char *token;
pFile = fopen ("myfile.txt" , "r");
if (pFile == NULL) perror ("Error opening file");
else {
if ( fgets (mystring , 100 , pFile) != NULL )
/* get the first token */
token = strtok(mystring, delimiters);
/* walk through other tokens */
while( token != NULL )
{
printf( " %s\n", token );
token = strtok(NULL, delimiters);
}
fclose (pFile);
}
return 0;
}
- 第一个问题
fgetc()
return 是一个 int
您不能将 EOF
存储在 char
变量中。
- 您应该检查
fopen()
是否 return NULL
。
你可以用这个技巧来读这样的字
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX_BUFFER_SIZE 256
char **load_words_from_file(const char *filename)
{
size_t wordcount;
size_t charcount;
char buffer[MAX_BUFFER_SIZE];
int chr;
FILE *file;
char **words;
void *pointer;
file = fopen(filename, "r");
if (file == NULL)
return NULL;
wordcount = 0;
charcount = 0;
words = NULL;
while ((chr = fgetc(file)) != EOF)
{
/* it's a white space or it exceeded buffer size, it's a word delimiter */
if ((isspace(chr) != 0) || (charcount >= sizeof(buffer) - 1))
{
/* 'nul' terminate 'buffer' for strcpy() and strlen() */
buffer[charcount] = '[=10=]';
pointer = realloc(words, (1 + wordcount) * sizeof(char *));
if (pointer == NULL) /* failure, free allocated memory and return NULL */
goto failure;
words = pointer;
words[wordcount] = malloc(1 + charcount);
charcount = 0; /* reset character count */
if (words[wordcount] == NULL)
goto failure;
strcpy(words[wordcount], buffer);
wordcount += 1;
}
else
{
/* store the character and count it */
buffer[charcount] = (char)chr;
charcount += 1;
}
}
pointer = realloc(words, (1 + wordcount) * sizeof(char *));
if (pointer == NULL)
goto failure;
words = pointer;
words[wordcount] = NULL; /* this will let you know when to stop fetching words */
fclose(file);
return words;
failure:
for (size_t i = 0 ; i < wordcount ; ++i)
free(words[i]);
free(words);
return NULL;
}
int
main()
{
const char *filename = "your-file-name-here";
char **words = load_words_from_file(filename);
size_t counter = 0;
if (words == NULL)
{
printf("no words found in the file\n");
return -1;
}
while (words[counter] != NULL)
{
printf("%zuth word: %s\n", 1 + counter, words[counter]);
free(words[counter]); /* this program will not use it again */
counter += 1;
}
free(words);
return 0;
}
strtok()
方法也可以,但更难理解。
注意goto
的使用,这是一个良性的使用,虽然有些人认为goto
总是有害的,但事实并非如此,这样使用它会使程序坚持DRY 原理.
您可以将扫描集与 fscanf 或 sscanf 一起使用。此扫描集 %29[a-zA-Z]
读取小写和大写英文字符,并在遇到不在集合中的字符时停止。 29 限制了要读取的最大字符数,以免覆盖缓冲区,word[30]
。当 fscanf 失败时,else 将从文件中读取一个字符并让 fscanf 再次尝试读取另一个单词。
这个也是用命令行传入文件读取为argv[1].
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[])
{
char word[30] = {'[=10=]'};
int ch = 0;
FILE *pf = NULL;
if ( argc != 2) {//command requires program name and a file name
printf ( "useage: program filename\n");
return 1;
}
if ( ( pf = fopen ( argv[1], "r")) == NULL) {
perror ( "could not open file");
return 1;
}
while ( 1) {
if ( ( fscanf ( pf, "%29[a-zA-Z]", word)) == 1) {
printf ( "%s\n", word);
}
else {
if ( ( ch = fgetc ( pf)) == EOF) {//read one character and check for end of file
break;
}
//could do something here with the value of ch if needed
}
}
printf ( "--DONE--\n");
return 0;
}
这将为每个单词分配一个数组。添加单词时,使用 realloc 扩展数组。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main( int argc, char *argv[])
{
char **words = NULL;//pointer for words
char **temp = NULL;
char word[30] = {'[=11=]'};
int ch = 0;
int each = 0;
int found = 0;
int count = 0;
int wordsize = 0;
FILE *pf = NULL;
if ( argc != 2) {//command requires program name and a file name
printf ( "useage: program filename\n");
return 1;
}
if ( ( pf = fopen ( argv[1], "r")) == NULL) {
perror ( "could not open file");
return 1;
}
while ( 1) {
if ( ( fscanf ( pf, "%29[a-zA-Z]", word)) == 1) {
found = 0;
for ( each = 0; each < wordsize; each++) {
if ( strcmp ( words[each], word) == 0) {
found = 1;
break;
}
}
if ( found == 0) {
wordsize += 1;// increment number of words
temp = realloc ( words, wordsize * sizeof ( char *));//reallocate for another word
if ( temp != NULL) {
words = temp;
words[wordsize - 1] = malloc ( strlen ( word) + 1);//malloc for the word itself
if ( words[wordsize - 1] != NULL) {
strcpy ( words[wordsize - 1], word);
}
else {
printf ( "malloc failed\n");
wordsize -= 1;
break;
}
}
else {
printf ( "realloc failed\n");
wordsize -= 1;
break;
}
}
printf ( "%s\n", word);
}
else {
if ( ( ch = fgetc ( pf)) == EOF) {//read one character and check for end of file
break;
}
//something could be done with ch if needed
}
}
printf ( "--DONE Reading file--\n");
for ( each = 0; each < wordsize; each++) {// print each word
printf ( "%s\n", words[each]);
}
count = 0;
printf ( "Enter a word to search for\n");
if ( ( scanf ( "%29[a-zA-Z]", word)) == 1) {
for ( each = 0; each < wordsize; each++) {
if ( strcmp ( words[each], word) == 0) {
printf ( "Found %s at index %d\n" word, each);
count++;
}
}
printf ( "Found %s %d times\n" word, count);
}
for ( each = 0; each < wordsize; each++) {//release memory
free ( words[each]);
}
free ( words);
return 0;
}
我目前正在从一个文件中收集输入,但我的程序将每个字母而不是每个单词分隔到 char 数组中。如何更改我的代码以获取每个单词?
char c, fileName[20];
FILE *f;
void getFile() {
f = fopen(fileName, "r");
while((c = fgetc(f)) != EOF) {
printf("%c",c);
}
fclose(f);
}
改用fscanf(3)
char word[256], *p;
while(fscanf(f, "%s", &word) != EOF) {
printf("%s\n", word);
/* break down word into individual chars */
for(p=word; *p; p++) {
printf("%c ", *p);
}
printf("\n");
}
你可以使用 char * fgets ( char * str, int num, FILE * stream );
然后使用 char *strtok(char *str, const char *delim)
例如
#include <stdio.h>
int main()
{
FILE * pFile;
char mystring [100];
const char delimters[2] = " ,:";
char *token;
pFile = fopen ("myfile.txt" , "r");
if (pFile == NULL) perror ("Error opening file");
else {
if ( fgets (mystring , 100 , pFile) != NULL )
/* get the first token */
token = strtok(mystring, delimiters);
/* walk through other tokens */
while( token != NULL )
{
printf( " %s\n", token );
token = strtok(NULL, delimiters);
}
fclose (pFile);
}
return 0;
}
- 第一个问题
fgetc()
return 是一个int
您不能将EOF
存储在char
变量中。 - 您应该检查
fopen()
是否 returnNULL
。
你可以用这个技巧来读这样的字
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX_BUFFER_SIZE 256
char **load_words_from_file(const char *filename)
{
size_t wordcount;
size_t charcount;
char buffer[MAX_BUFFER_SIZE];
int chr;
FILE *file;
char **words;
void *pointer;
file = fopen(filename, "r");
if (file == NULL)
return NULL;
wordcount = 0;
charcount = 0;
words = NULL;
while ((chr = fgetc(file)) != EOF)
{
/* it's a white space or it exceeded buffer size, it's a word delimiter */
if ((isspace(chr) != 0) || (charcount >= sizeof(buffer) - 1))
{
/* 'nul' terminate 'buffer' for strcpy() and strlen() */
buffer[charcount] = '[=10=]';
pointer = realloc(words, (1 + wordcount) * sizeof(char *));
if (pointer == NULL) /* failure, free allocated memory and return NULL */
goto failure;
words = pointer;
words[wordcount] = malloc(1 + charcount);
charcount = 0; /* reset character count */
if (words[wordcount] == NULL)
goto failure;
strcpy(words[wordcount], buffer);
wordcount += 1;
}
else
{
/* store the character and count it */
buffer[charcount] = (char)chr;
charcount += 1;
}
}
pointer = realloc(words, (1 + wordcount) * sizeof(char *));
if (pointer == NULL)
goto failure;
words = pointer;
words[wordcount] = NULL; /* this will let you know when to stop fetching words */
fclose(file);
return words;
failure:
for (size_t i = 0 ; i < wordcount ; ++i)
free(words[i]);
free(words);
return NULL;
}
int
main()
{
const char *filename = "your-file-name-here";
char **words = load_words_from_file(filename);
size_t counter = 0;
if (words == NULL)
{
printf("no words found in the file\n");
return -1;
}
while (words[counter] != NULL)
{
printf("%zuth word: %s\n", 1 + counter, words[counter]);
free(words[counter]); /* this program will not use it again */
counter += 1;
}
free(words);
return 0;
}
strtok()
方法也可以,但更难理解。
注意goto
的使用,这是一个良性的使用,虽然有些人认为goto
总是有害的,但事实并非如此,这样使用它会使程序坚持DRY 原理.
您可以将扫描集与 fscanf 或 sscanf 一起使用。此扫描集 %29[a-zA-Z]
读取小写和大写英文字符,并在遇到不在集合中的字符时停止。 29 限制了要读取的最大字符数,以免覆盖缓冲区,word[30]
。当 fscanf 失败时,else 将从文件中读取一个字符并让 fscanf 再次尝试读取另一个单词。
这个也是用命令行传入文件读取为argv[1].
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[])
{
char word[30] = {'[=10=]'};
int ch = 0;
FILE *pf = NULL;
if ( argc != 2) {//command requires program name and a file name
printf ( "useage: program filename\n");
return 1;
}
if ( ( pf = fopen ( argv[1], "r")) == NULL) {
perror ( "could not open file");
return 1;
}
while ( 1) {
if ( ( fscanf ( pf, "%29[a-zA-Z]", word)) == 1) {
printf ( "%s\n", word);
}
else {
if ( ( ch = fgetc ( pf)) == EOF) {//read one character and check for end of file
break;
}
//could do something here with the value of ch if needed
}
}
printf ( "--DONE--\n");
return 0;
}
这将为每个单词分配一个数组。添加单词时,使用 realloc 扩展数组。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main( int argc, char *argv[])
{
char **words = NULL;//pointer for words
char **temp = NULL;
char word[30] = {'[=11=]'};
int ch = 0;
int each = 0;
int found = 0;
int count = 0;
int wordsize = 0;
FILE *pf = NULL;
if ( argc != 2) {//command requires program name and a file name
printf ( "useage: program filename\n");
return 1;
}
if ( ( pf = fopen ( argv[1], "r")) == NULL) {
perror ( "could not open file");
return 1;
}
while ( 1) {
if ( ( fscanf ( pf, "%29[a-zA-Z]", word)) == 1) {
found = 0;
for ( each = 0; each < wordsize; each++) {
if ( strcmp ( words[each], word) == 0) {
found = 1;
break;
}
}
if ( found == 0) {
wordsize += 1;// increment number of words
temp = realloc ( words, wordsize * sizeof ( char *));//reallocate for another word
if ( temp != NULL) {
words = temp;
words[wordsize - 1] = malloc ( strlen ( word) + 1);//malloc for the word itself
if ( words[wordsize - 1] != NULL) {
strcpy ( words[wordsize - 1], word);
}
else {
printf ( "malloc failed\n");
wordsize -= 1;
break;
}
}
else {
printf ( "realloc failed\n");
wordsize -= 1;
break;
}
}
printf ( "%s\n", word);
}
else {
if ( ( ch = fgetc ( pf)) == EOF) {//read one character and check for end of file
break;
}
//something could be done with ch if needed
}
}
printf ( "--DONE Reading file--\n");
for ( each = 0; each < wordsize; each++) {// print each word
printf ( "%s\n", words[each]);
}
count = 0;
printf ( "Enter a word to search for\n");
if ( ( scanf ( "%29[a-zA-Z]", word)) == 1) {
for ( each = 0; each < wordsize; each++) {
if ( strcmp ( words[each], word) == 0) {
printf ( "Found %s at index %d\n" word, each);
count++;
}
}
printf ( "Found %s %d times\n" word, count);
}
for ( each = 0; each < wordsize; each++) {//release memory
free ( words[each]);
}
free ( words);
return 0;
}