JoaoSkate 0 Denunciar mensagem Publicado 19 de Março de 2016 Boas, eu tenho um programa onde através da consola insiro uma string com espaços e numeros, por exemplo: AA BBB 11. Sendo que essa string pode no maximo ter 10 carateres, o meu problema está em repartir a string em partes e usar cada uma dessas partes para diferentes fins: char comando[10]; printf("Introduza o comando: "); scanf("%s", comando); printf("%s",comando); sendo que eu posso alterar a ordem pelo que aparecem os números e as as letras, por exemplo: AA BBB 11 ou GG 1 XXXX ou 1 AA há sempre um espaço a separar cada conjunto de carateres, mas eu quero ler tudo como uma só string e depois usar as diversas partes sem os espaços. um dos problemas com que me estou a deparar é com o facto de o %s ler apenas uma palavra ate encontrar um espaço, ao encontrar coloca um '/0' no vetor e acaba, eu queria que lesse uma 'frase'', já pensei em usar o gets() no entanto o gets emite sempre warings no compilador Obrigado. Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
HappyHippyHippo 1151 Denunciar mensagem Publicado 19 de Março de 2016 usa o fgets IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
JoaoSkate 0 Denunciar mensagem Publicado 19 de Março de 2016 (editado) obrigado, penso que o fgets já envolve apontadores, eu ainda não dei nas aulas, pelo que penso que este exercicio envolve outro método. eu estou a tentar o seguinte: char a; char a1[4]; char a2[4]; printf("Introduza o comando:"); scanf("%c %s %s", &a,a1, a2); printf("teste: %c \n",a); printf("teste: %s \n",a1); printf("teste: %s \n",a2); supondo que afinal os comando que eu introduza na consola são sempre do seguinte tipo, POR EXEMPLO: Y 1 X ZZZ 10 X NNN MMM existe alguma forma de fazer com que quando o scanf me pede "coisas" ele encerre quando o utilizador prime enter na consola e guarda nas variaveis a informação inserida, isto é, por exemplo quando introduzo : Y 1, o Y vai ser guardado na variavel a, e o 1 na variável a1, o problema é que o programa/a consola fica sempre à espera que seja inserido um 3º valor para guardar na variavel a2. (nao sei se me fiz entender, isto é um pouco dificil de explicar) Ou seja, resumidamente, existe alguma forma de fazer com que este scanf por vezes receba só duas variaveis outras vez só uma varial e outras vezes as 3 variaveis? Editado 19 de Março de 2016 por JoaoSkate Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
HappyHippyHippo 1151 Denunciar mensagem Publicado 20 de Março de 2016 obrigado, penso que o fgets já envolve apontadores, eu ainda não dei nas aulas, pelo que penso que este exercicio envolve outro método. envolve praticamente tantos apontadores como a função gets #define LINE_MAX_SIZE 1024 char line[LINE_MAX_SIZE]; fgets(line, LINE_MAX_SIZE, stdin); existe alguma forma de fazer com que quando o scanf me pede "coisas" ele encerre quando o utilizador prime enter na consola e guarda nas variaveis a informação inserida, isto é, por exemplo quando introduzo : Y 1, o Y vai ser guardado na variavel a, e o 1 na variável a1, o problema é que o programa/a consola fica sempre à espera que seja inserido um 3º valor para guardar na variavel a2. (nao sei se me fiz entender, isto é um pouco dificil de explicar) Ou seja, resumidamente, existe alguma forma de fazer com que este scanf por vezes receba só duas variaveis outras vez só uma varial e outras vezes as 3 variaveis? não IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
JoaoSkate 0 Denunciar mensagem Publicado 20 de Março de 2016 (editado) okay certo, eu estou a tentar agora da seguinte forma: #include int main() { char val1, val2[4], val3[4]; scanf("%c %[^ ] %s", &val1, val2, val3); /* testando :*/ printf("%c\n",val1); printf("%s\n",val2); printf("%s\n",val3); return 0; } o problema surge quando a linha introduzida na consola nao obedece ao seguinte formato: a bbb ccc por exemplo se for neste formato: a bbb , já nao funciona ou seja, se eu introduzir na consola a bbb, e der <enter> ele fica sempre à espera de um terceiro para guardar na val3. eu já pensei eu fazer tipo if val3[0] == '\n' então acaba , mas nao funcionou muito bem Editado 20 de Março de 2016 por JoaoSkate Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
HappyHippyHippo 1151 Denunciar mensagem Publicado 20 de Março de 2016 como te foi dito : usa o fgets para ler a linha toda do buffer de entrada, depois, usa a função sscanf para interpretar a linha lida IRC : sim, é algo que ainda existe >> #p@p Portugol Plus Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
JoaoSkate 0 Denunciar mensagem Publicado 21 de Março de 2016 Bem eu tentei fazer ainda de outra maneira: #include #include struct Valores { char v1; char v2[4]; char v3[4]; }; int main() { struct Valores b; printf("insira linha: "); scanf("%c %s %[^'\n']*'\n'", &b.v1, b.v2, b.v3); //para testar printf("comando 1: %c\n",b.v1); printf("comando 2: %s\n",b.v2); printf("comando 3: %s\n",b.v3); return 0; } parte do meu problema já esta resolvi, que era guardar as partes de uma linha completa por exemplo A BBB CCC, em diferentes variàveis, o preblema que me falta resolver é o deu por exemplo a linha completa inserida na consola apena receber o 1º elemento ou apenas o 1º e o 2º por exemplo, eu pretendo que ao ser 'dado' <enter> o programa fique apenas com os valores inseridos até entao e nao que fique à espera dos restantes (nao sei se me faço entender) escrevi este código com base numa dúvida já colocada aqui no forum que voçe HappyHippo respondeu a um utilizador sobre o que significava : %[^\n]\n ao que voçe respondeu " quer dizer : come tudo até encontrar um caracter especificado nesta lista" (que neste caso é o caracter '\n'. o \n final quer dizer que após ter encontrado esse mesmo caracter na pesquisa anterior, lê-o também, descartando/removendo do stream lido" No entanto entanto nao aconteçe o que eu esperava isto é quando primo <enter> (que penso que representa o \n), o programa continua à espera de mais... foi por isso que alterei para: %[^'\n']*'\n pois como \n é um carater penso que tenho de colocar entre ' ', mas o resultado foi exatamente o mesmo. se puder dar uma ajuda agradecia Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
JoaoSkate 0 Denunciar mensagem Publicado 21 de Março de 2016 (editado) Okay acho que estou quase a resolver o problema, mas algo me está a escapar, o que tenho agora é: #include <stdio.h> struct Valores { char v1; char v2[4]; char v3[4]; }; int main() { struct Valores b; printf("insira a linha: "); scanf("%[^\n]c %[^\n]s %[^\n]\n", &b.v1, b.v2, b.v3); printf("comando 1: %c\n",b.v1); printf("comando 2: %s\n",b.v2); printf("comando 3: %s\n",b.v3); return 0; } eu sei que a linha que vai ser inserida na consola pode ter as seguinte formas (com um espaço entre cada <>): - < 1 carater> <uma string><outra string> , ex: a bbb ccc ou - < 1 carater> <uma string> , ex: a bbb ou < 1 carater> ex: a ou < 1 carater> <uma string><um inteiro> ex: a bbb 100 ou < 1 carater> <um inteiro> ,ex: a 1 problema: na consola quando insiro por exemplo: a bbb ccc o resultado é: insira linha: a bbb ccc //printf comando 1: a comando 2: bbb ccc // o resultado esperado aqui era apenas bbb (sem o espaço antes, e sem o ccc depois) comando 3: ccc // o resultado esperado aqui era apenas ccc(sem o espaço antes) ou quando a linha inserida é do tipo ex: a 10 o output é o correto insira linha: a bbb ccc comando 1: a comando 2: comando 3: //excepto um carater estranho que aqui apareçe Editado 21 de Março de 2016 por JoaoSkate Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
PsySc0rpi0n 8 Denunciar mensagem Publicado 21 de Março de 2016 Eu como estou também a tenter aprender alguma coisa, vou deixar a minha sugestão... Atenção que não faço ideia se é funcional ou não: 1 - Ler toda a string com o fgets 2 - Usar o strstr e o strtok para extrair as 3 strings para 3 variáveis separadas ou para usá-las directamente. Mas também são sei se percebi bem o que pretendes fazer. Se eu percebi, queres inserir 3 strings de tamanhos variáveis até um máximo de 10 caracteres, separadas por espaços e depois poder usar essas 3 strings separadamente. É isto? Eu desses scape characters não percebo nada, mas pelo que vi no teu último code, no scanf não estás a ignorar os "new line" characters em vez dos espaços? Depois acho que há outro problema no code: o facto de poderes alterar a ordem dos dados porque depois vais estar a guardar dados nas variáveis de tipos de dados errados. Ou pelos menos, quando fizeres o printf das variáveis, podes estar a contar com a representação do "inteiro" 10 e ser imprimido o caractér ASCII correspondente ao inteiro 10. Não sei se consegues contornar facilmente este problema! Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
Flinger 50 Denunciar mensagem Publicado 22 de Março de 2016 (editado) O PsySc0rpi0n tem razão em todos os pontos. Com o scanf tens de saber o pattern a ler de antemão. Isso vai completamente contra o que tu queres. O mais correcto é leres a string inteira primeiro (com o fgets por exemplo), e depois fazer o parse da string, com o sscanf, ou palavra a palavra, através do uso do strtok, como sugeriu o PsySc0rpi0n, ou mesmo caracter a caracter, se não quiseres/não estiveres à vontade com o strtok. Os patterns do teu scanf estão completamente errados... %[^\n]s isto faz match com tudo excepto o '\n'. Ou seja consome-te todo o input não deixando nada para o 3.º parâmetro. A única razão pela qual o teu exemplo "a bbb ccc" dá o 3.º parâmetro como ccc é por estares a escrever o segundo parâmetro fora da variável... A título de exemplo, aumenta as tuas strings de 4 caracteres para 400, e vê o resultado... Já agora, uma ajuda: Retirado do "man scanf" Return Value These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure. The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs. EOF is also returned if a read error occurs, in which case the error indicator for the stream (see ferror(3)) is set, and errno is set indicate the error. Ou seja o scanf retorna o número de variáveis que consegui efectivamente ler, logo a=scanf("%[^\n]c %[^\n]s %[^\n]\n", &b.v1, b.v2, b.v3); printf("resultado scanf:%d\n",a); vai-te dizer quantos argumentos conseguiu ler. Editado 22 de Março de 2016 por Flinger 1 Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
JoaoSkate 0 Denunciar mensagem Publicado 22 de Março de 2016 obrigado pela ajuda, eu estava a tentar evitar usar o fgets, e usar apontadores, porque eu estou ainda a aprender e ainda nao cheguei a essas partes mais complicadas, eu já fui ver como funciona o fgets mas nao percebi mt bem com funciona. Mas ainda vou tenntar ver de novo. no entanto arranjei agora uma forma simples para ler uma frase completa: #include #define DIM 10 #include int main() { int c, i=0; char vetor[DIM]; while(i vetor[i++] = c; vetor[i] = '\0'; printf("%s\n",vetor); //testando return 0; } agorapor exemplo quando insiro : a bbb ccc fica guardado no vetor esta string "a bbb ccc" e eu quero partir essa string em 3 e guardar em novas strings(vetores) o a, o bbb, ccc, para guardar o 'a' eu já tentei fazer por exmplo nova_varialvel=vetor[0] mas dá me segmetation fault, e o que estava a pensar fazer para o bbb e o cc era usar o strcpy, para copiar a string completa a bbb ccc para uma nova string bbb Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
PsySc0rpi0n 8 Denunciar mensagem Publicado 22 de Março de 2016 (editado) A tua variável vector[DIM], indirectamente é um ponteiro. O fgets lê uma string do buffer de entrada para uma variável já declarada. Por exemplo: fgets (vector, DIM, stdin); lê uma string do buffer de entrada 'stdin' e armazena-a em 'vector', isto sem entrar em muitos detalhes. No entanto, para depois tratares da string após ter sido armazenada em 'vector', precisas de saber, pelo menos dois detalhes: 1-o fgets também guarda em 'vector', o <enter> que usamos quando inserimos a string. 2-o fgets adiciona um carácter especial à string que a sinaliza como tal. Ou seja, uma string, para ser uma string tem que ter obrigatoriamente este caractér especial no final. É o NULL character ou terminador de string, acho que é assim o nome. Exemplo: A string "o rato roeu a rolha" lida com o fgets, fica com este aspecto depois de guardada em 'vector': o rato roeu a rolha\n\0 O \n é o <enter>e o \0 é o tal NULL char que sinaliza a string, como sendo uma string. Ps: se o teu último código funciona, eu não consigo perceber como. Falta pelo menos um parêntesis no argumento do while, a variável 'c' não inicializada poder ser um problema é a variável 'i' se for a que controla o loop while e sem ser alterada, vai impedir o Code do while de ser executado e ainda o factor de não ver nenhuma função de leitura do buffer de entrada. Editado 22 de Março de 2016 por PsySc0rpi0n Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
Flinger 50 Denunciar mensagem Publicado 22 de Março de 2016 (editado) Recomendamos o fgets, porque a versão simples, o gets é altamente desaconselhada por questões de segurança. Mas para efeitos práticos, o fgets com o valor do 3.º parágrafo stdin, é efectivamente igual ao gets mas mais seguro. Quanto ao primeiro parâmetro, o char *, estás usar o mesmo que usas no scanf e no printf, por isso nada de novo. char *fgets(char *s, int size, FILE *stream) int scanf(const char *format, ...); A única coisa que precisas saber é: int main() { char input[1024]; fgets(input,1024,stdin); printf("%s",input); } O fgets lê-te uma linha inteira (até ao enter,incluído), com um tamanho máximo de 1024 - 1 (este último char fica para o \0). Editado 22 de Março de 2016 por Flinger 1 Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
PsySc0rpi0n 8 Denunciar mensagem Publicado 22 de Março de 2016 Eu também só vou dizer isto mais uma vez: Usa o fgets... Se ainda nãod este apontadores nas aulas, então também não podes usar vectores de strings! Nem vectores, de uma forma geral... Partilhar esta mensagem Ligação para a mensagem Partilhar noutros sites
Crie uma conta ou ligue-se para comentar
Só membros podem comentar
Criar nova conta
Registe para ter uma conta na nossa comunidade. É fácil!
Registar nova contaEntra
Já tem conta? Inicie sessão aqui.
Entrar Agora