我知道有一个同名的问题,但它对我不起作用。 我正在制作一个家庭编译器,返回属于一种语言的单词。
要分析的词语在这个载体中:
char *cadenas[]= {"123", "4567L", "5a23", '\0'};
现在我想通过控制台输入单词,但字符串不能在C中使用,我该怎么办? (可能没有制作矩阵)
void getCadenas(char *cadenas[]){
printf("Enter cadenas to be analyzed ('z' to scape) \n \n");
char cadena[15];
gets(cadena);
int x=0;
while(cadena[0]!='z'){
strcpy(cadenas[x],cadena);
x++;
gets(cadena);
}
}
答案 0 :(得分:1)
如果我正确理解您的问题,您希望用户能够输入多个字符串,直到他/她键入z
看看这段代码是否可以帮到你。字符串将根据请求存储在cadenas
数组中。
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define MAX_CADENAS 100
#define MAX_CADENA_LEN 255
int getCadenas(char **cadenas){
int x=0;
char cad[MAX_CADENA_LEN+1];
printf("Enter cadenas to be analyzed ('z' to scape) \n \n");
while(x<MAX_CADENAS) {
scanf("%s", cad);
if (strcmp(cad,"z")==0)
break;
cadenas[x] = malloc(strlen(cad)+1);
strcpy(cadenas[x], cad);
x++;
}
return x;
}
char *cadenas[MAX_CADENAS];
int main() {
int num, i;
num = getCadenas(cadenas);
for (i=0;i<num; i++) {
printf("%s\n", cadenas[i]);
}
}
注意:代码假设您事先知道输入字符串的最大数量(100)。它还假定每个输入字符串的最大大小(255个字符)
注1:不推荐使用gets
。另外,您可能希望使用scanf
而不是fgets
。
注2:本代码仅供说明之用。它为每个输入字符串分配内存,但它假定这样做没有错误(即它不检查malloc
返回的内容)。
注3:不再使用时必须释放已分配的内存块(提示:在cadenas
数组中循环并使用free
)
答案 1 :(得分:0)
假设你不介意使用固定大小的字符串和数组,这里修改了原始程序:
#include <stdio.h>
#include <string.h>
#define MAX_CADENAS 100
#define CADENA_LIMIT 1000
// ...
void getCadenas(char cadenas[MAX_CADENAS][CADENA_LIMIT]){
printf("Enter cadenas to be analyzed ('z' to scape) \n \n");
int x;
for(x=0; x<MAX_CADENAS-1; x++){
char cadena[CADENA_LIMIT];
fgets(cadena, CADENA_LIMIT, stdin);
// fgets will copy the newline character, we don't want that
int cadenaLength=strlen(cadena);
if(cadena[cadenaLength-1]=='\n')
cadena[cadenaLength-1]='\0';
if(strcmp(cadena, "z")==0) break;
strcpy(cadenas[x], cadena);
}
cadenas[x][0]='\0';
}
// ...
首选fgets
,因为您可以防止固定大小的字符串溢出。不幸的是它也复制了换行符,所以我有代码来处理它。结果是您最初指定的表单中的数组(除了它以""
结尾,我们认为这是您在评论中所追求的内容)。
你可以在C中读取任意大小的字符串,就像在其他语言中一样,但你需要用malloc()
and co来实现它。分配动态大小的内存主要由函数malloc
,calloc
,realloc
和free
控制。 这会使程序不可避免地变得更复杂。这是一种方法:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// ...
char *getCadena(){
int length=0, capacity=1, character;
char *cadena=malloc(1); // sizeof(char) is always 1
while((character=getchar())!=EOF){
if(character=='\n') break;
// Add character to string
length++;
if(capacity<length){
capacity*=2;
cadena=realloc(cadena,capacity);
}
cadena[length-1]=character;
}
// Add terminator to cadena
length++;
if(capacity<length){
capacity*=2;
cadena=realloc(cadena,capacity);
}
cadena[length-1]='\0';
return cadena;
}
char **getCadenas(){
printf("Enter cadenas to be analyzed ('z' to scape) \n \n");
int length=0, capacity=1;
char **cadenas=malloc(sizeof(char *));
for(;;){
char *cadena=getCadena();
if(strcmp(cadena,"z")==0){
free(cadena);
break;
}
// Add pointer to cadenas array
length++;
if(capacity<length){
capacity*=2;
cadenas=realloc(cadenas,capacity*sizeof(char *));
}
cadenas[length-1]=cadena;
}
// Add NULL to end of cadenas
length++;
if(capacity<length){
capacity*=2;
cadenas=realloc(cadenas,capacity*sizeof(char *));
}
cadenas[length-1]=NULL;
return cadenas;
}
void freeCadenas(char **cadenas){
int i=0;
while(cadenas[i]!=NULL){
free(cadenas[i]);
i++;
}
free(cadenas);
}
// ...
这与上一个函数大致相同,但最终应使用freeCadenas
,并且我使用NULL
而不是""
来结束数组,这是惯常的。
代码要长得多,但它是非常典型的更复杂的C代码,具有更少的任意限制。实际上,真正的C代码通常具有更强大的错误处理能力以及用于管理动态数组的更通用的功能。但是,如果您真的设法制作这个“家庭编译器”,那么您将自己解决所有问题。