I've got a text file containing a bunch of random data from programs I've written:
hdfs45 //the hdsf part stays the same everytime, but the number always changes
I'm trying to parse this line of data into two parts, the hdfs part and the 45 part (to be later converted to an int)
I've tried something along the lines of this:
Char * a, * b;
char str[100];
FILE* ptr;
ptr = fopen("test.txt","r"); // opens sucessfully
while(fgets(str,100,file))
{
a = strtok(str," \n");
printf("%s",a); // but this prints the whole string
}
The data will be random, for setting the delimiter to "45" is useless. However the first part "hdfs" is always the same,any help would be much appreciated.
If "hdfs" never changes, then you can simply convert the characters after the first 4 into a number, i.e.:
int num = atoi(str + 4);
str[4] = '\0';
In your example, num will equal 45, and str will equal hdfs.
You can't use strtok because there is nothing to tokenize (you can't use a delimiter), try:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char str[100] = "hdfs45";
char *ptr;
long num;
ptr = strpbrk(str, "012345679");
if (ptr) {
num = strtol(ptr, NULL, 10);
*ptr = '\0';
printf("%s -> %ld\n", str, num);
}
return 0;
}
Related
This question already has an answer here:
How to use sscanf in loops?
(1 answer)
Closed 4 years ago.
I used sscanf to segment one string taken from the input and store every token in a structure. The problem is that sscanf only reads the first word of the string and doesn't move ahead to the next word, printing the same token over and over. Here's the code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define dim 30
typedef struct string {
char* token[dim];
}string;
int main() {
string* New = (string *)malloc(dim*sizeof(string));
char* s;
char buffer[dim];
int i = 0, r = 0, j = 0;
s = (char*)malloc(sizeof(char*));
printf("\nString to read:\n");
fgets(s, dim, stdin);
printf("\nThe string is: %s", s);
while(sscanf(s, " %s ", buffer) != EOF) {
New->token[i] = malloc(dim*sizeof(char));
strcpy(New->token[i], buffer);
printf("\nAdded: %s", New->token[i]);
++i;
}
}
For example, if i give "this is a string" as an input, sscanf will only get the word "this" multiple times without moving on to the next word.
You need to increment the pointer of the source sscanf() reads from, so that it won't read from the same point, again and again.
Furthermore, the memory dynamically allocated for s by you didn't make any sense. It was too less in any case. By the call to fgets() later in the code I can see you meant to say s = malloc(dim * sizeof(char));, so I went ahead and fixed that.
Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define dim 30
typedef struct string {
char* token[dim];
} string;
int main() {
string* New = malloc(dim*sizeof(string));
char* s;
char buffer[dim];
int i = 0;
s = malloc(dim * sizeof(char));
fgets(s, dim, stdin);
printf("The string is: %s\n", s);
char* ptr = s;
int offset;
while (sscanf(ptr, "%s%n", buffer, &offset) == 1) {
ptr += offset;
New->token[i] = malloc(strlen(buffer) + 1);
strcpy(New->token[i], buffer);
printf("Added: %s\n", New->token[i]);
++i;
}
// do work
for(int j = 0; j < i; ++j)
free(New->token[i]);
free(New);
free(s);
return 0;
}
Output:
The string is: this is a string
Added: this
Added: is
Added: a
Added: string
PS: I am not sure about the schema of structures you have in mind, maybe you need to spend a moment or two, thinking about that twice; I mean whether your design approach is meaningful or not.
PPS: Unrelated to your problem: Do I cast the result of malloc? No!
Edit: As #chux said, " " in " %s%n" of sscanf() serves no purpose. I changed it to "%s%n".
Moreover, in order to reserve exactly as much memory as needed (which is the thing to do, when dealing with dynamic memory allocation), New->token[i] = malloc(dim*sizeof(char)); was changed to New->token[i] = malloc(strlen(buffer) + 1);.
I am trying to create a char array based on a single ASCII code. The folowing code does not compile correctly, even though "num" is cast to a char:
//Returns the ASCII counterpart of a number, such as 41 = A, 42 = B, 43 = C, etc.
char numToASCII(int num) {
char[] string = {(char)num, "\0"};
return string;
}
For the task that I am given, it is very important that "string" be a character array/string and not a single char. Any help would be appreciated.
The array must be initialized to constant expressions and your function should return a pointer if you want to return an array.
If you just want to return a char, then use the following code instead:
char numToASCII(int num) {
return (char)num;
}
If you want to return a string which contains the character, then you should use the following code:
#include <stdlib.h>
char *numToASCII(int num) {
/*
* Use malloc to allocate an array in the heap, instead of using a
* local array. The memory space of local array will be freed after
* the invocation of numToASCII.
*/
char *string = malloc(2);
if (!string)
return 0;
string[0] = num;
string[1] = 0;
return string;
}
Use the free() function to free the space allocated by malloc().
Try this..
You want to find the character for the ASCII code,then try this code:
#include<stdio.h>
int main()
{
int num;
printf("\nEnter ASCII Code Number:\t");
scanf("%d", &num);
printf("\nASCII Value of %d: \t%c", num, num);
printf("\n");
return 0;
}
In this code it will get the ASCII code from the user and it will print the character for the ASCII code as default.
Not sure if this helps but pulling text from a file comes back as ascii, I needed a string and got around it by checking the string length, sorry for extra steps as I too am very new.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char firstbuff[yourchoice];
char secondbuff[yourchoice];
char sentence[yourchoice];
int stringlenght;
fp = fopen("test.txt", "r");
//Here add a means of counting the lines in the file as linecount
for(int j = 0; j < linecount; j++)
{
fgets(firstbuff; 1000; fp);
//get string length and use for loop to individually ascii copy as characters into array
stringlength = strlen(firstbuff);
for(int i = 0; i < stringlength; i++)
{
secondbuff[i] = (char)firstbuff[i];
}
//string concat
strcat(sentence, secondbuff);
}
printf("%s\n", sentence);
fclose(fp);
}
Ok, so I'm going to explain my program.
It takes a text file that's setup as such: in pairs, first line being the title of an experiment, and the second line being 10 numbers separated by spaces. It saves the first lines of pairs in *experiments and the second lines of pairs in data. The last line is *** END *** which is what it's supposed to end with.
For some reason *** END *** doesn't end the program. Any ways I can fix this? I'm assuming it's because fgets gives str blank spaces (99 chars total) so that the string in quotes will never be equal to str?
Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int var;
int i=0,j,k;
char seps[] = " ";
char *experiments[20];
int data[10][20];
char str[100]; // make sure that this size is enough to hold the single line
char *ptr, *token;
int no_line=1;
while(fgets(str,100,stdin) != NULL && strcmp(str,"*** END ***"))
{
if(no_line % 2 == 0)
{
k=0;
token = strtok (str, seps);
while (token != NULL)
{
sscanf (token, "%d", &var);
data[i][k++] = var;
token = strtok (NULL, seps);
}
i++;
/*read integer values from the string "str" using sscanf, sscanf can be called in a loop with %d untill it fails */
}
else
{
ptr = strdup(str);
experiments[i] = ptr;
/*strore string in your variable "experiments" , before copying allocate a memory for the each entry */
}
no_line++;
}
for(j=0;j<i;j++)
{
printf("%s",experiments[j]);
for(k=0;k<10;k++)
{
printf("%d ",data[j][k]);
}
printf("\n");
}
}
You're declaring i here ...
int i,j,k;
... and using it here ...
data[i][k++] = var;
Nowhere do you initialize i. Also, why does data need to be a 2D array? Can't it just be a 1D array?
int data[10];
...
data[k++] = var;
From this code, int i seems to be declared, but not initialized?
data[i][k++] = var;
It may be helpful to use Eclipse or Code Block IDE to try small testable codes because it has all sorts of syntax and error checking features.
I got text file with information: (100;200;first).Can anybody tell me how to seperate this information into three arrays: Min=100,Max=200 and Name=first. I have tried this whith
c=getc(inp);
i=atoi(szinput);
but its read 10 for first time and 00 for second... and so on in loop
c saves 10 not 1, so i cant get the right information for arrays...
So the array Min stores 1000 not 100
Thanks.
use scanf or fscanf like this:
scanf("(%d;%d;%[^)])",&min,&max,str);
You could do something like the following
FILE *file;
char readBuffer[40];
int c;
file = fopen("your_file","r");
while ((c=getc(file))!= EOF)
{
strcat(readBuffer, c);
if( (char) c == ';')
//this is the delimiter. Your min, max, name code goes here
}
fclose(file);
Here is a cool, simple tutorial on how to do that.
Please note that you'll need to adapt the example a little bit, but that should not be too difficult.
Also you could try to find a library that does the job, I'm sure there are a lot of such libraries for C :)
Use strtok():
#include <stdio.h>
#include <string.h>
int main() {
char input[] = "100;200;first";
char name[10];
int min, max;
char* result = NULL;
char delims[] = ";";
result = strtok(input, delims);
// atoi() converts ascii to integer.
min = atoi(result);
result = strtok(NULL, delims);
max = atoi(result);
result = strtok(NULL, delims);
strcpy(name, result);
printf("Min=%d, Max=%d, Name=%s\n", min, max, name);
}
Output:
Min=100, Max=200, Name=first
How can you code this in C language if the output is like this? I need strings format of the code because our topic is strings.
#include <stdio.h>
#include <stdlib.h>
void main()
{
char my_string[50];
printf("Enter a word:");
scanf("%s", my_string);
printf("Enter a word:");
scanf("%s", my_string);
// Some unknown code here...
// this part is my only problem to solve this.
getch();
}
Output:
Hello -> (user input)
World -> (user input)
HWeolrllod -> (result)
Okay, you need to do some investigating. We don't, as a general rule, do people's homework for them since:
it's cheating.
you'll probably get caught out if you copy verbatim.
it won't help you in the long run at all.
The C library call for user input that you should use is fgets, along the line of:
char buffer[100];
fgets (buffer, sizeof(buffer), stdin);
This will input a string into the character array called buffer.
If you do that with two different buffers, you'll have the strings in memory.
Then you need to create pointers to them and walk through the two strings outputting alternating characters. Pointers are not an easy subject but the following pseudo-code may help:
set p1 to address of first character in string s1
set p1 to address of first character in string s1
while contents of p1 are not end of string marker:
output contents of p1
add 1 to p1 (move to next character)
if contents of p2 are not end of string marker:
output contents of p2
add 1 to p2 (move to next character)
while contents of p2 are not end of string marker:
output contents of p2
add 1 to p2 (move to next character)
Translating that into C will take some work but the algorithm is solid. You just need to be aware that a character pointer can be defined with char *p1;, getting the contents of it is done with *p1 and advancing it is p = p + 1; or p1++;.
Short of writing the code for you (which I'm not going to do), there's probably not much else you need.
void main()
{
char my_string1[50],my_string2[50]; int ptr;
ptr=0;
printf("Enter a word : ");
scanf("%s",my_string1);
printf("enter a word");
scanf("%s",my_string2);
while(my_string1[ptr]!='\0' && my_string2[ptr]!='\0')
{
printf("%c%c",my_string1[ptr],my_string2[ptr]);
ptr++;
}
if(my_string1[ptr]!='\0')
{
while(my_string1[ptr]!='\0')
{ printf("%c",my_string1[ptr]);
ptr++;
}
}
else
{
while(my_string2[ptr]!='\0')
{printf("%c",my_string2[ptr]);
ptr++;
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char my_string1[50],my_string2[50];
int i,l1=1,l2=0;
printf("Enter a word:");
scanf("%s", my_string1);
printf("Enter a word:");
scanf("%s", my_string2);
l1=strlen(my_string1); /* Length of 1st string */
l2=strlen(my_string2); /* Length of 2nd string */
if(l1==l2)
{
for(i=0;i<l1;i++)
{
printf("%c%c",my_string1[i],my_string2[i]);
}
}
else
{
printf("Length of the entered strings do not match");
}
}
This is your required code.
You can see that output needs to be a String containing all chars of User String1 and User String2 one by one...
You can do this like...
//add #include<String.h>
int l1=strlen(s1);
int l2=strlen(s2);
if(l1!=l2)
{
printf("length do not match");
return 0;
}
char ansstr[l1+l2];
int i,j=0,k=0;
for(i=0;i<l1+l2;i=i+2)
{
ansstr[i]=s1[j];
ansstr[i+1]=s2[k];
j++;
k++;``
}
//ansstr is your answer
Ok, here's your code. Come on guys, if he asked here it means he can't solve this.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char str1[] = "abcdefghijklmopq";
char str2[] = "jklm";
int len1 = strlen(str1);
int len2 = strlen(str2);
int c1 = 0, c2 = 0;
int max = (len1 > len2) ? len1 : len2 ;
char *result = malloc(len1 + len2);
for(c1 = 0; c1 <= max; c1++) {
if(c1 < len1)
result[c2++] = str1[c1];
if(c1 < len2)
result[c2++] = str2[c1];
}
result[c2] = 0;
printf("\n%s\n", result);
return 0;
}
Basically the loop picks up a character from str1 and appends it to result. Then it picks a character, which stands in the same position as the first from str2 and appends it to result, just as before. I increment c2 by 2 every time because I'm adding 2 chars to result. I check if c1 is bigger that the length of the strings because I want to copy only the characters in the string without the terminating \0. If you know that your strings have the same length you can omit these ifs.