I am very new in C, I have little idea about sprintf but I can't fulfill my requirement.
I have a char * variable which contains string like below :
date=2013-12-09 time=07:31:10 d_id=device1 logid=01 user=user1 lip=1.1.1.1 mac=00:11:22:33:44:55 cip=2.2.2.2 dip=3.3.3.3 proto=AA sport=22 dport=11 in_1=eth1 out_1=
I want an output as
2013-12-09#07:31:10#device1#01#user1#1.1.1.1#00:11:22:33:44:55#2.2.2.2#3.3.3.3#AA#22#11#eth1##
if some value is null after = it should print ## in sequence.
I am not going to give you exact code but I will give you some links that will help you.
strchr :: You can use this find the position of '=' in the string.
Now, copy the string after the position of '=' till you find a 'space'.
Whenever you will find a 'space', write a '#' in the buffer.
Keep doing this, till you encounter a '\0'. Write '##' to buffer when you have encountered '\0'
Append that with a '\0'.
Ex:: C function strchr - How to calculate the position of the character?
example by use strtok, strchr, sprintf
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
const char *data = "date=2013-12-09 time=07:31:10 d_id=device1 logid=01 user=user1 lip=1.1.1.1 mac=00:11:22:33:44:55 cip=2.2.2.2 dip=3.3.3.3 proto=AA sport=22 dport=11 in_1=eth1 out_1=";
char *work = strdup(data);//make copy for work
char *output = strdup(data);//allocate for output
char *assignment; //tokenize to aaa=vvv
size_t o_count = 0;//output number of character count
for(assignment=strtok(work, " "); assignment ;assignment=strtok(NULL, " ")){
o_count += sprintf(output + o_count, "%s#", strchr(assignment, '=')+1);
}
printf("%s", output);
free(work);
free(output);
return 0;
}
Related
I am reading a .txt file which contains data in a random form i.e. it contains integers and strings mixed in it.
Sample .txt file:
this is a 22 string 33 sorry222 stack33ing
still yysi288 2nd line
I want to read the file and differentiate all valid string i.e. which do not contain integers concatinated with them. And store those strings in an array.
Any leads on how to differentiate?
You can use #include <ctype.h> for that purpose.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int checkString( const char s[] ) {
unsigned char c;
while ( ( c = *s ) && ( isalpha( c ) || isblank( c ) ) ) ++s;
return *s == '\0';
}
void printNonNumericWords(char str[]) {
int init_size = strlen(str);
char delim[] = " ";
char *ptr = strtok(str, delim);
while(ptr != NULL)
{
if (checkString(ptr))
printf("'%s'\n", ptr);
ptr = strtok(NULL, delim);
}
printf("\n");
}
Call function like this.
printNonNumericWords(this is a 22 string 33 sorry222 stack33ing");
First: I can´t write the programm for you. It is your task to do and beside this i can´t even change things on your code or at least suggest to alter, because you are not providing any code. I can give you only a dusty leading algorithm for this case:
All the words you might see, are not valid strings in the file. It is only one string containing white space characters between each sequence of characters which appear for you as one word or separated string, but it doesn´t.
You have to get the whole string from the file first and store it into an char array, lets name it source, using fgets():
#include <stdio.h>
FILE *input;
char source[200];
input = fopen("text.txt","r");
fgets(source, 200, input);
After that you need to make those "words" separated strings by transport each of the characters of the source string, one after another, to other char arrays and quit writing the characters to them as soon as the space character or the NUL-byte after the last word is provided in the source string. Don´t forget to make a Nul-Byte (\n) terminating each string.
Thereafter you check each, now valid and separated string, if it either is a string that contains numbers or a string without any number.
I want to parse a string into a note and octave. For example if the user inputs "A#4", (A#)-note that will be stored in (char n) and (4)- octave that will be stored in (char o). Why am I getting blanked line instead of 4 as output after A#?
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main()
{
string src = get_string();
char *n;
char *o;
char *note = "ABCDEFG#b";
char *octave = "12345678";
o = strtok(src, note);
n = strtok(src, octave);
printf("%s\n", n);
printf("%s\n", o);
}
Output:
A#
Can you please point to error and suggest a solution?
strtok is not the function you want to use in this instance.
When you call it, it alters the string, replacing the character that matches the deliminator with a NUL so you'll lose the character you're looking for as the note. The second time you call it with src, the string will appear empty and it won't find anything - you're meant to call it on subsequent times with the first parameter set to NULL so that it knows you're searching for the next token in the same string.
You might want to use strspn which counts the number of characters that match your set (ie note) or strpbrk that finds the first character that matches.
Or you could traverse the string yourself and use strchr like this
char *pos;
for(pos=src;*pos!='\0';pos++)
{
if(strchr(note,*pos))
{
// *pos is a note character
}
}
Whatever you use, you'll need to build a new string based on your results as the original string won't have space to put NUL terminators inside to separate out the two parts you're looking for.
I'm having some problem with my code. I need to use strtok() in c to output the words "Sing" and "Toy" (which are both in between the words "Due" and "De") in the string "Date WEEk Dae Due Toy De Dae i Date Due Sing De". I tried to use the if statement found in the code to explicitly output the words "Sing" and "Toy" but my code would not produce any output and it had no warnings during compilation. I'm only a beginner at C so please be patient with me. I heard that other functions such as strstr() might be able to do the same job as strtok() so if those other functions are much more convenient to use, do not hesitate to use those functions instead. Thank you.
Summary: I'm trying to get the words in between "Due" and "De" in the string above using strtok() and is it possible to do so or should I use another function?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char string[]="Date WEEk Dae Due Toy De Dae i Date Due Sing De";
char*pch;
pch=strtok(string,"De");
while(pch!=NULL){
if((*(pch-1)=='a')&&(*(pch-2)=='u'))
printf("%s\n",pch);
pch=strtok(NULL,"De");
}
return 0;
}
Keep in mind that the second parameter of strtok() is a delimeter list:
C string containing the delimiter characters.
These can be different from one call to another.
They way it's now in your code, the token will be taken after each capital D and lower case e.
For the case mentioned in your description, it's more suitable to workaround the problem using strstr().
you should pass " " as second argument to strtok
If you want to print Sing, check if pch is not null and strcmp(pch,"Sing") == 0 then print Sing
Find "Due" followed by a space
char *due = strstr(string, "Due ");
Find "De" preceded by a space
char *de = strstr(string, " De");
Check for errors
if (!due || !de) exit(EXIT_FAILURE);
Print what is between
printf("%.*s\n", (int)(de - due - 4), due + 4);
Use strstr like this
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void){
char string[]="Date WEEk Dae Due Toy De Dae i Date Due Sing De";
char *pre_word = "Due", *post_word = "De";
size_t pre_word_len = strlen(pre_word), post_word_len = strlen(post_word);
char *p = string, *pre, *post;
while(pre = strstr(p, pre_word)){//find pre word
if((pre == string || isspace((unsigned char)pre[-1])) &&
isspace((unsigned char)pre[pre_word_len])){//word check
if(post = strstr(pre + pre_word_len, post_word)){//find post word
if(isspace((unsigned char)post[-1]) &&
(isspace((unsigned char)post[post_word_len]) || !post[post_word_len])){//word check
*post = 0;//The original string is changed
char word[32], dummy[2];
if(1==sscanf(pre + pre_word_len, "%31s %1s", word, dummy)){//There is one word between words
printf("'%s'\n", word);
}
}
p = post + post_word_len;//set next search position
} else {
break;//Since post_word does not exist, it ends loop.
}
}
}
return 0;
}
I'm trying to make a simple program where parts of other strings are appended to another string. When I run this code, it doesn't output anything. Sorry, my C knowledge is very low. All help appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char stuff[100] = "Y";
char test[] = "hello", test2[] = "shelllo";
strcat(stuff, test[1]);
strcat(stuff, test2[0]);
printf("%s\n", stuff);
return 0;
}
You need to remove array index from your strcat which should look like:
strcat(stuff, test);
strcat(stuff, test2);
Note that test and test2 are strings, but test[1] and test2[0] are just individual characters (e and s) - strcat works with string, not individual characters.
If you want to copy just part of a string (ie skipping first few characters), then use pointer arithmetic
strcat(stuff, test + 1); // skip 1st character of test (ie start copying from `e`)
or,
strcat(stuff, test2 + 3); // skip 3 characters of test2 (ie starting copying from `l`)
You are calling strcat with a char argument instead of a pointer to char, the behavior is undefined.
Here are solutions to copy portions of strings:
using strncat(): it copies no more than a given number of characters to the end of its first argument.
using snprintf() with the %.*s format. The precision field for the %s format specifies the maximum number of characters to copy from the string. It can be specified as a decimal number or as a * in which case the precision is passed as an int argument before the string argument.
Here is an example:
#include <stdio.h>
#include <string.h>
int main(void) {
char stuff[100];
char test[] = "Hello";
char test2[] = "The world is flat";
/* using strncat */
strcpy(stuff, test);
strncat(stuff, test2 + 3, 6);
printf("%s\n", stuff);
/* safer version using snprintf */
snprintf(stuff, sizeof stuff, "Hello %.*s\n", 5, test2 + 4);
printf("%s\n", stuff);
return 0;
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I've been trying to learn C programming by reading a textbook, but am confused about how strings and substrings work.
I have an idea of what strings and substrings are from java, but can't figure out the syntax in C.
Here's a question from the book that I thought might be easy, but I can't get it.
Write and test a function hydroxide that returns a 1 for true if its string argument ends in the substring OH.
It recommends testing the function with KOH and NaCl.
Also, how would I remove and add letters at the end of the string?
Like, if for some reason I wanted to change NaCl to NaOH?
Any help and explanations would be really appreciated.
ETA:
I guess what I'm most confused on is how to make the program look at the last two letters in the string and compared them to OH.
I'm also not sure how to pass strings to functions.
String is a sequence of characters that ends with special null-terminated character '\0'. If there is no \0, functions that work with string won't stop until the \0 symbol is found. This character may happen in any place after the end of pseudo string (I mean a string without \0) and only then stop.
The following example shows the necessity of this null-terminated character:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char string[] = "Hello!";
printf("original string:\n%s\n\n", string);
memset(string, '-', 5);
printf("memset doesn't affect the last two symbols: '!' and '\\0':\n%s", string);
memset(string, '-', 6);
printf("\n\nmemset doesn't affect the last symbol: '\\0':\n%s\n\n", string);
memset(string, '-', 7);
printf("memset affects all symbols including null-terminated one:\n%s", string);
return 0;
}
/* OUTPUT:
original string:
Hello!
memset doesn't affect the last two characters: '!' and '\0':
-----!
memset doesn't affect the last character: '\0':
------
memset affects all characters including null-terminated one:
-------#↓#
*/
Substring is a char sequence that is in a string. It may be less or equal to the string.
Suppose, "NaOH" is a string. Then substring may be: "N", "a", "O", "H", "Na", "aO", "OH", "NaO", "aOH", "NaOH". To find whether substring is in the string or not you can use strstr function. It's prototype is char * strstr ( char * str1, const char * str2 );.
This code shows this function's results:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *ptrCh = NULL;
ptrCh = strstr("hello", "h");
printf("ptrCh: %p\n", ptrCh);
printf("%s\n\n", ptrCh);
ptrCh = strstr("hello", "z");
printf("ptrCh: %p\n", ptrCh);
printf("%s\n\n", ptrCh);
return 0;
}
/* OUTPUT:
ptrCh: 00403024
hello
ptrCh: 00000000
(null)
*/
As for the first printf, it prints characters beginning from the position of 'h' and when it reaches null-terminated character, which is next after 'o', it stops, exactly as in previous program.
To make your program more interactive, you can declare array and then a pointer to it. Array size must be enough to store the longest formula. Suppose, 100 will be enough:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char buf[100] = {0};
char *ptr = &buf[0];
scanf("%s", ptr);
// printf() gets a pointer as argument
printf("%s\n", ptr);
// printf() gets also a pointer as argument.
// When you pass arrays name without index to a function,
// you pass a pointer to array's first element.
printf("%s", buf);
return 0;
}
And as for rewriting letters in the end of the string. Here is a small program that does it. Pay attention at comments:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char buf[100] = {0};
char formula[100] = {0};
char compound[100] = {0};
char *ptr = &buf[0];
char *pFormula = &formula[0];
char *pCompound = &compound[0];
printf("Enter formula: ");
scanf("%s", pFormula);
printf("Enter chemical compound: ");
scanf("%s", pCompound);
// Copying the first chemical elements without the last
// several that will be replaced by another elements.
strncpy(ptr, pFormula, strlen(pFormula) - strlen(pCompound));
// Adding new compound to the first elements.
// Function also adds a null-terminated character to the end.
strncat(ptr, pCompound, strlen(pCompound));
printf("The new chemical compound is: ");
printf("%s", ptr);
return 0;
}
/* OUTPUT:
Enter formula: NaOH
Enter chemical compound: Cl
The new chemical compound is: NaCl
*/
In C, we use null-terminated strings. That is the "invisible", 0 value. Not ASCII "0", but the zero value, like 8-bit 0x00. You can represent it in literal text with '\0' or "\0" or unquoted 0, however, in a literal string it is redundant because most functions like strcmp() or strstr() or strcat() all expect and work with null terminated strings. Null char is the stops sign for the C standard string functions.
One easy way to implement this with C library calls is to test for existence of the substring and then test that substring's length, which verify it is at end of string.
Assume buf is some big string buffer, char buf[1024] and char *temp is a temporary variable.
temp = strstr(buf, "OH") returns the pointer to "OH" if exists in buf at any offset.
strlen(temp) Get length of temp, if at end of string, it will be 2 (doesn't include null terminator), so if the original string is "OHIO" or "SOHO" it wont match because it'll be 4 and 3 respectively.
The above is the core of the code, not the full robust implementation. You need to check for valid return values, etc.
char buf[1024];
char *temp;
strcpy(buf, "NaOH");
if((temp = strstr(buf, "OH")) != 0)
{
// At this point we know temp points to something that starts with "OH"
// Now see if it is at the end of the string
if(strlen(temp) == 2)
return true; // For C99 include stdbool.h
return false;
}
You could get obscure, and check for the null terminator directly, will be a smidge quicker. This code is safe as long as it is inside the if() for strstr(), otherwise never do this if you don't know a string is a least N characters long.
if(temp[2] == '\0')
return true; // For C99 include stdbool.h
As far as appending to a string, read the docs on strcat. Keep in mind with strcat, you must have enough space already in the buffer you are appending into. It isn't like C++ std::string or Java/C# string where those will dynamically resize as needed. In C, you get to do all of that yourself.