Fórum Ubuntu Linux - PT
Suporte Técnico => Programação e Scripts => Tópico iniciado por: mhkgalvez em 04 de Junho de 2010, 15:22
-
Olá pessoal, tenho uma função que desejo que retorne um vetor de Strings em C.
Estou usando char *hasError(char *stream)
, mas não dá certo.
Minha função main:
int main (int argc,char *argv[])
{
char *text;
text = takeEptSpc("5 5 ");
char *ret;
ret = hasError("5 5 ");
int i = 0;
for (i = 0; i < 5; i++)
printf("%s", ret[i]);
return 0;
}
Na execução, ele retorna erro de segmentação.
O que posso fazer para retornar corretamente um vetor de strings?
-
mhkgalvez poste o código completo, senão num tem como saber onde tá a falha :P
-
Função hasError:
char *hasError(char *stream, char mode)
{
int i = 0, htmlCodeLenght = 1;
int *listGt, *listLt;
int countLt = 0, countGt = 0;
char *htmlCode = stream;
char *out[5];
stream = takeEptSpc(stream);
//Initializing out array
for (i = 0; i < 5; i++)
{
out[i] = "";
}
//End initializing out array
//Looking at '<' and '>' chars
htmlCodeLenght = countString(htmlCode);
for (i = 0; i < htmlCodeLenght; i++)
{
if (htmlCode[i] == '<')
{
countLt++;
}
if (htmlCode[i] == '>')
{
countGt++;
}
}
if (countGt != countLt)
{
printf("Error 1 of HTML Tag. The tags weren't opened or closed correctly.");
out[0] = "Error 1 of HTML Tag. The tags weren't opened or closed correctly.";
if (mode == 'o')
return out;
}
listLt = (int *) malloc(countGt * sizeof(int));
listGt = (int *) malloc(countGt * sizeof(int));
for (i = 0; i < countGt; i++)
{
if (htmlCode[i] == '<')
{
listLt[i] = i;
}
if (htmlCode[i] == '>')
{
listGt[i] = i;
}
}
for (i = 0; i < countGt; i++)
{
if (listGt[i] < listLt[i])
{
printf("Error 2 of HTML Tag. The tags weren't opened or closed correctly.");
out[1] = "Error 2 of HTML Tag. The tags weren't opened or closed correctly.";
if (mode == 'o')
return out;
}
}
//End looking at '<' and '>' chars
//Looking at order of '<' and '>' chars
int ind = 0;
for (i = 0; i < countGt; i++)
{
while (htmlCode[ind] != '<' && htmlCode[ind] != '>')
ind++;
if (htmlCode[ind] == '>')
{
printf("Error 3 of HTML Tag. The tags weren't opened or closed correctly.");
out[2] = "Error 3 of HTML Tag. The tags weren't opened or closed correctly.";
if (mode == 'o')
return out;
}
if (htmlCode[ind] == '<')
{
while (htmlCode[ind] != '>')
{
if (htmlCode[ind] == '<')
{
printf("Error 4 of HTML Tag. The tags weren't opened or closed correctly.");
out[3] = "Error 4 of HTML Tag. The tags weren't opened or closed correctly.";
if (mode == 'o')
return out;
}
ind++;
}
}
}
//End looking at order of '<' and '>' chars
printf("Código HTML sem nenhuma falha");
return out;
}
Considero que não tem erro nela, pois os vetores são iniciados com vazio no início. Por isso, creio que o erro esteja no tipo de retorno da função.
-
Realmente...parece que tá certo...
Você colocou todas as bibliotecas? Tá usando o gcc como compilador?
-
Não seria porque você tá retornando "out" que está declarado como "char *out[5]" que é um vetor de ponteiros? Na função main você tá atribuindo o retorno da função para um ponteiro.
Eu fiz um teste simples aqui sobre esse retorno e deu erro.
-
Pessoal, o que acontece é que fazia algum tempo que eu programava em C, e essa questão de trabalhar com strings em C sempre me confundiu, então, vejam bem:
-> Para eu criar um texto simples eu faria char *texto e atribuiria o valor da string, por exemplo:
texto = "olá";
No caso de um vetor de strings, eu faria char *text[10] onde 10 seria o número de strings. E, na função hasError este tipo de uso está funcionando.
O problema é quando retorno isso. Eu tentei usar, como assinatura da função hasError um retorno char[], ou char hasError(...)[], ou ainda char[10], etc. Mas antes mesmo de compilar no NetBeans 6.8 acusa erro se sintaxe.
O problema de fazer sem ser uma variável de ponteiros é que, eu acho [me corrijam se eu estiver errado] que não dará para eu colocar as strings do tamanho que eu quiser. Desta maneira, ficarei limitado.
Volto a dizer que estou enferrujado. Haveria, então, alguma forma de contornar este problema?
-
No caso de um vetor de strings, eu faria char *text[10]
Ai você tá declarando um vetor de ponteiros com 10 posições, é como se fosse um ponteiro para ponteiro. Com isso você pode criar uma matriz de strings.
Para um vetor de strings basta "char text[10]", ai você tem um vetor de strings com 10 posições, ou usando ponteiros "char *text = (char*)maloc(10*sizeof(char));".
-
No caso de um vetor de strings, eu faria char *text[10]
Ai você tá declarando um vetor de ponteiros com 10 posições, é como se fosse um ponteiro para ponteiro. Com isso você pode criar uma matriz de strings.
Para um vetor de strings basta "char text[10]", ai você tem um vetor de strings com 10 posições, ou usando ponteiros "char *text = (char*)maloc(10*sizeof(char));".
pra deixar mais simples ainda você pode inicializar o valor do vetor na declaração mesmo:
char text[10]="olá";
-
Tah mas e o problema do retorno!??? ???
-
Tah mas e o problema do retorno!??? ???
ainda não sei...
mas na sua função main você passou um parâmetro errado em 'hasError()', ou melhor dizendo, você só passou um parâmetro, mas a 'hasError()' tava definida para receber dois.
-
O problema é que em C puro você não tem realmente um tipo de variável para strings. O que é feito então em C é utilizar um vetor caracteres "como se fosse uma string", mas você não pode esquecer que isso na verdade é apenas um vetor de caracteres. Lembre-se também que um vetor nada mais é do que um ponteiro para o primeiro elemento do vetor.
Isso quer dizer que você deve sim dizer qual o tamanho do vetor quando declarar uma variável usada para guardar uma "string".
Quando você escreve algo como
hello = "hello";
o que acontece é que o "hello" é um array de char e a variável 'hello' recebe o endereço desse array de char então está tudo bem nesse caso.
Se você quiser copiar strings de uma variável para outra você deve usar a função strcpy. Se você simplesmente usar "=" você estará na verdade copiando o endereço de uma variável para a outra e ambas vão apontar para a mesma região de memória. Compile e rode o programa abaixo para ver esse efeito.
int main(int argc, char *argv[])
{
char* hello = "Hello Cruel World";
char hello2[20];
char* hello3;
/* Vamos copiar usando strcpy */
strcpy(hello2,hello);
hello3 = hello;
/* Vamos imprimir o conteudo de cada variável */
printf("%s\n",hello);
printf("%s\n",hello2);
printf("%s\n",hello2);
/* Vamos imprimir o valor dos ponteiros para cada variável */
printf("%p\n",hello);
printf("%p\n",hello2);
printf("%p\n",hello3);
/* Note que hello e hello3 possuem o mesmo ponteiro */
return 0;
}
Da mesma forma, se você tentar comparar strings com
stringA == stringB
você estará comparando apenas se os ponteiros são iguais e não se o conteúdo das variáveis corresponde a mesma string. A maneira correta é utilizar a função strcmp. No exemplo acima se você fizer se você fizer o teste "hello==hello2" vai dar falso, mesmo que ambas as variáveis tenham o mesmo conteúdo.
Esse site
http://www.cplusplus.com/reference/clibrary/cstring/ (http://www.cplusplus.com/reference/clibrary/cstring/)
é uma boa referência.
Ps: Na verdade não tenho muita experiência com C puro, já que quase sempre programo em C++ (std::string é de fato um tipo para strings e é bem melhor de se trabalhar que um vetor de char puro), então se eu disse alguma besteira deem um desconto, mas em geral trabalhar com "strings" em C é bem chato.
-
Já experimentou usar o gdb e correr o programa passo a passo a ver onde é que quebra? Ou usar printscreens para ir vendo onde quebra?
-
Darcamo está correto na interpretação sobre "strings" em C.
Eis uma possível solução para o seu problema:
#include <malloc.h>
#include <stdio.h>
#include <string.h>
static const char STR1[] = "String 1";
static const char STR2[] = "String 2";
/* Um macrozinho só para facilitar a vida... */
#define COPY_CONS_STRING(a, i, s) \
(a)[(i)] = (char *)malloc(sizeof(char)*strlen((s))+1); \
strcpy((a)[(i)], (s));
/*
Como o array de strings pode ser definido como um "char **",
precisamos passar um "char ***" para podermos alocar o vetor e retorná-lo.
*/
int GetStringArray(char ***strArray)
{
char **out;
#define NUM_ITEMS 2
out = (char **)malloc(sizeof(char *) * NUM_ITEMS);
COPY_CONST_STRING(out, 0, STR1);
COPY_CONST_STRING(out, 1, STR2);
*strArray = out;
/* Retorna o número de strings no array de strings */
return NUM_ITEMS;
}
/* Libera strings alocadas */
void FreeStringArray(char **strArray, int count)
{
int i;
for (i = 0; i < count; i++)
{
free(strArray[i]);
strArray[i] = NULL;
}
free(strArray);
}
int main(int argc, char **argv)
{
int strCount, i;
char **strings;
/* Pega array de strings */
strCount = GetStringArray(&strings);
for (i = 0; i < strCount; i++)
printf("%s\n", strings[i]);
/* Libera array de strings */
FreeStringArray(strings, strCount);
return 0;
}
Mas, você pode achar mais fácil mexer com a STL, em C++, usando os templates/classes "vector" e "string".
[]s
Fred