Storing a variable integer with a char Array in C [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I want to extract, edit and re-concatenate a string that contains an integer. How does this get done?
char str_test[] = "CAT ";
int count = 10;
//(1) something here to combine str_test and count stored in some variable
char str_new[] = ????;
//(2) something else here to extract the 10 and +1?
//such that if I print str_new, it gives me "CAT 11"
????

You can use sprintf to write a formatted number to a string, and you can use snprintf to find out how many characters are required.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Return a newly allocated string containing String followed by Number
converted to decimal. The caller is responsible for freeing the memory.
*/
static char *ConcatenateIntToString(const char *String, int Number)
{
// Get the number of non-null characters in String.
size_t Length = strlen(String);
/* Allocate space for:
the characters in String,
the characters needed to format Number with "%d", and
a terminating null byte.
*/
char *Result = malloc(
Length
+ snprintf(NULL, 0, "%d", Number)
+ 1);
// Test whether the allocation succeeded.
if (!Result)
{
fprintf(stderr, "Error, unable to allocate memory.\n");
exit(EXIT_FAILURE);
}
// Copy the characters from String.
memcpy(Result, String, Length);
// Append the formatted number and a null terminator.
sprintf(Result + Length, "%d", Number);
// Return the new string.
return Result;
}
int main(void)
{
char *NewString = ConcatenateIntToString("CAT ", 11);
printf("The new string is %s.\n", NewString);
free(NewString);
}

Related

sscanf loop only reads first input multiple times [duplicate]

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);.

Extract sub string from a string based on a condition [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have an input string in the format: name1#float1 name2#float2 ... nameN#floatN. It's always delimited by '#' and ' '.
Example:
ash#19.96 ram#12.3 driver#10.2
It should display the name of the person having the smallest values.
How can it be solved?
Output:
driver
You can combone the strtok and sscanf functions to solve your problem.
For first, you have to tokenize your string using ' ' (white-space) as delimiter, then extract the number from each token to find the token with smallest number. Every time you find a token with smaller number than the current, extract the name from that token and store the new possibly smallest number. Here is an example:
#include <string.h>
#include <stdio.h>
#include <float.h>
int main() {
char str[] = "ash#19.96 ram#12.3 driver#10.2";
char result[256] = { 0 };
char *token, *sep_ptr;
float value, min = FLT_MAX; /* set 'min' to the maximum of float */
/* tokenize 'str' and walk through the tokens */
for(token = strtok(str, " "); token != NULL; token = strtok(NULL, " ")) {
value = FLT_MAX;
/* process the current token if it contains a '#' character */
if(sep_ptr = strchr(token, '#')) {
sscanf(sep_ptr, "#%f", &value); /* extract value */
/* check if the new number is smaller than current 'min' */
if(value < min) {
strcpy(result, (*sep_ptr = '\0', token)); /* extract name */
min = value;
}
}
}
puts(result);
return 0;
}
The (*sep_ptr = '\0', token) part of the code above simply replaces the '#' character to null character before performing the copy from token to result. (The mentioned expression uses the comma operator.)
The following code implements a getSubstrSmallestNumber() function which uses the strtok() function which changes the input buffer. If you don't want that you can first copy the string. The good point about changing the input buffer is that no memory allocation is needed for the found sub string. The strtok() writes a null terminator '\0' where the specified delimiter is found if it's called.
The getSubstrSmallestNumber() function can called with specific delimiters, here '#' and ' '. Each number will be converted to double with strtod() and checked if it smaller than before. If it's smaller the corresponding token will be saved. After the while loop finished (if strtok() found no more tokens) the saved token (smallest double) will be returned.
Note that the code does no error checking this should be considered to be implemented as well.
Full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
char* getSubstrSmallestNumber(char* input, char* numberDelimiter, char* strDelimiter)
{
char* tokenStr;
double minNumber = DBL_MAX;
char* minToken = NULL;
for (tokenStr = strtok(input, numberDelimiter);
tokenStr != NULL;
tokenStr = strtok(NULL, numberDelimiter))
{
char* numberStr = strtok(NULL, strDelimiter);
double number = strtod(numberStr, NULL);
if (number < minNumber)
{
minNumber = number;
minToken = tokenStr;
}
}
return minToken;
}
int main()
{
char input[] = "ash#19.96 ram#12.3 driver#10.2";
printf("<%s>\n", getSubstrSmallestNumber(input, "#", " "));
return 0;
}
Output:
<driver>
I put '<' and '>' around the string in the printf() call to show that the returned string by getSubstrSmallestNumber() is really just driver and nothing more like a space for example.
You can use strrok available in C string library and for parsing float you can use atof function but the atof function seems to be unreliable in some cases, though. In that case you can write your own implementation according to your needs.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <float.h>
#define SIZE 1000
int main() {
char input[SIZE], smallest[SIZE], name[SIZE];
const char s[2] = "#";
char *token;
float val = FLT_MAX;
while(scanf("%s", input) != EOF) {
token = strtok(input, s);
strcpy(name, token);
token = strtok(NULL, s);
float curVal = atof(token);
if(curVal < val) {
val = curVal;
strcpy(smallest, name);
}
}
printf("Smallest value : %s\n", smallest);
return 0;
}
When i tested it seemed to show correct output:
~/Documents/src : $ ./a.out
ram#12.3
driver#10.2
ash#19.96
Smallest value : driver
Hope that helps!

How to check certain chars in string in C? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Suppose ,I have to use only one string function and check if the string input by user contains all the chars a,e,i,o,u ...how do I do it?
(the chars mentioned above need not be contagious in the string input by user.)
Please help.
You can use the function strchr
char *strchr(const char *str, int c)
This function searches for the first occurrence of the character c (an unsigned char) in the string pointed to by the argument str.
If the character c is not present then null is returned.
One of the possible implementation is shown here -
#include <stdio.h>
#include <string.h>
#define SIZE 5
int main ()
{
char toCheck[5] = {'a','e','i','o','u'};
// Array of characters required in the string.
char userstring[25]; // User String
int i;
printf("Enter your string : \n");
scanf("%s",userstring);
for(i=0;i<SIZE;i++ ){
if(strchr(userstring,toCheck[i])==NULL)
break;
}
if(i==SIZE)
printf("All Required Characters present");
else printf("All Required Characters not present");
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
bool containsAll(const char *input, const char *contains){
bool check[256] = { false };
while(*input){
check[(unsigned char)*input++] = true;
}
while(*contains){
if(!check[(unsigned char)*contains++])
return false;
}
return true;
}
int main(void){
char input[256];
fgets(input, sizeof input, stdin);
input[strcspn(input, "\n")] = 0;
if(containsAll(input, "aeiuo"))//"aeiuo\n"
puts("yes");
else
puts("no");
}

Passing strings as pointer to a function [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
It's a simple function for many but as a beginner, I've yet to overcome the pointer ghost specially when it comes to strings. I understand some of the examples of strcmp, strcpy, strlen as well as how the characters are assigned in the memory with a NULL terminator. I think I also get the point how a pointer variable in memory points to the address of a int var or char etc. and you assign them by dereferencing them to var/char, but whenever I try to write a code, the pointer ghost comes back to bite me.
So, here I'm trying to run this and doesn't work. I would appreciate if you could clarify this for me...
//GETNAME function should return a string that is not NULL and less than 20 characters
char getname (char *s1)
{
int i, n;
char s2[i];
printf ("Enter your name:" );
scanf ("%s", "s2");
if (s2 == NULL)
return 0;
else if(n<20)
for ( i=0, n =strlen (s2 + 1); i<n; i++)
*(s1+i) = s2[i]; //copy characters from s2 and point to chars of s1
return *s1;
}
int main (int argc, char *argv[])
{
char name[20];
char urname;
urname = getname(name);
printf (" Your name is : %s\n", urname);
getch();
return NULL;
}
Here are several errors; there may be more:
Uninitialized variable:
int i, n;
char s2[i];
i is not initialized here, yet you use it as if it was. What value should i have? Like this it is undefined behaviour.
Incorrect argument to scanf:
scanf ("%s", "s2");
The second parameter should be a pointer to the memory that you want the input to be written to, not a constant string. It should be:
scanf ("%s", s2);
Incorrect argument to strlen:
for ( i=0, n =strlen (s2 + 1); i<n; i++)
You want to add 1 to the string length not to the string itself, so it should be
for ( i=0, n = strlen(s2) + 1; i<n; i++)
General issues with getname, including return type:
char getname (char *s1)
Why is this function so complex? You could directly scanf into the parameter s1. You don't need s2 for anything. Also the return type is wrong. You return a pointer, not a single char. It should be:
char* getname(char *s1)
Not handling return value from getname properly:
char urname;
urname = getname(name);
getname returns a pointer to char, not a single char. It should be:
char* urname;
urname = getname(name);
As the previous post says that i is not initialised.
Also the line
scanf("%s", "s2");
Should be
scanf("%s", s2);
The lines
if (s2 == NULL)
return 0;
else if(n<20)
Is incorrect as s2 will not be NULL and n is not initialised
... That is for starters
I recommend you get a book and read it

C - Increment a number within a char

Is it possible to increment a number alone within a string?
So let's say I have:
char someString = "A0001";
Is there a way to increment the number '0001'? To make it A0002, A0003 etc?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *strinc(const char *str, int d, int min_width){
char wk[12];//12:max length of sizeof(int)=4
char *p;
int len, d_len, c;
c = len = strlen(str);
while(isdigit(str[--c]));
++c;
d += strtol(&str[c], NULL, 10);
if(d<0) d = 0;
d_len = sprintf(wk, "%0*d", min_width, d);
p = malloc((c+d_len+1)*sizeof(char));
strncpy(p, str, c);
p[c]='\0';
return strcat(p, wk);
}
int main(void){
char *someString = "A0001";
char *label_x2, *label_x3;
label_x2 = strinc(someString, +1, 4);
printf("%s\n", label_x2);//A0002
label_x3 = strinc(label_x2, +1, 4);
printf("%s\n", label_x3);//A0003
free(label_x2);
label_x2 = strinc("A0008", +5, 4);
printf("%s\n", label_x2);//A0013
free(label_x3);
label_x3 = strinc(label_x2, -8, 4);
printf("%s\n", label_x3);//A0005
free(label_x2);
free(label_x3);
return 0;
}
no u cannot do it because it is a constant
The simple answer is that there is no "easy" way to do what you're asking. You would have to parse the string, extract the numerical portion and parse into a number. Increment the number and then print that number back into your string.
You could try the following simple example to base something on...
EDIT: Just read BLUEPIXY's answer... he presents a nice function that will do it for you, return you a new string, which doesn't have the width restriction of my simple answer...
There are some points worth noting...
Use char someString[] = "A0001"; and not char *someString = "A0001";. The reason is that the former allocates memory on the stack for the string, the latter is a pointer to a string in memory. The memory location decided upon by the compiler in the latter case and is not always guaranteed to be writable.
Crappy #define for snprintf on Windows... not sure that's a good thing. The point is really use a safe buffer writing function that won't overflow the bounds of your array.
The snprintf format string "%0*u" Formats an unsigned integer with a minimum width specified by the argument to the left of the actual integer and the zero tells it to left pad with zeros if necessary.
If your number increases to a width greater than, in this case, 4 digits, the buffer won't overflow, but your answers will look wrong (I haven't put in any logic to increment the buffer size)
I am assuming the the format of the string is always a set of non-numerical-digits, followed by a set of numerical digits and then a null terminator.
Now the code...
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#ifdef WIN32
#define snprintf sprintf_s
#endif
int main(int argc, char* argv[])
{
/* Assume that the string format is letters followed by numbers */
/* Note use someString[] and NOT someString* */
char someString[] = "A0001";
char *start = someString;
char *end = start + strlen(someString); /* End points to the NULL terminator */
char *endOfParse;
char c;
unsigned long num;
ptrdiff_t numDigits;
/* Find first numeric value (start will point to first numeric
* value or NULL if none found */
while( true )
{
c = *start;
if( c == '\0' || isdigit(c) )
break;
++start;
}
if( c == '\0' )
{
printf("Error: didn't find any numerical characters\n");
exit(EXIT_FAILURE);
}
/* Parse the number pointed to by "start" */
num = strtoul(start, &endOfParse, 0);
if(endOfParse < end )
{
printf("Error: Failed to parse the numerical portion of the string\n");
exit(EXIT_FAILURE);
}
/* Figure out how many digits we parsed, so that we can be sure
* not to overflow the buffer when writing in the new number */
numDigits = end - start;
num = num + 1;
snprintf(start, numDigits+1, "%0*u", numDigits, num); /* numDigits+1 for buffer size to include the null terminator */
printf("Result is %s\n", someString);
return EXIT_SUCCESS;
}
You can't do it simply because its not as simple to machine as it looks to you. There are a lot of things you need to understand about what you are trying to do first. For example, What part of string are you taking as a number which is to be incremented?
Last digit only?
A number which will be followed by SINGLE alphabet?
A number which may be followed by any number of alphabets?
LAST number in a string, for example A33B43 would mean to increment 33 or 43?
When you have answers to all such questions, you can implement them in a function. One of the many possible approaches thereafter can be to make a new substring which will represent the number to be incremented(this substring is to be taken out from your someString). Then use atoi() to convert that string into number, increment the number and replace this incremented number as a string in someString.(someString needs to be String or char * btw).

Resources