Get string until first digit - c

I need to get all the characters before the first digit from an array.
I did this and it seems to work correctly:
#include <stdio.h>
int main() {
char temp[128] = {0};
char str_active[128] = {0};
sprintf(temp, "%s", "AB01");
printf("Complete string.: %s\n", temp);
int len = sizeof(temp) / sizeof(char);
int index = 0;
while (index < len) {
if (isdigit(temp[index])) {
break;
} else {
index++;
}
}
snprintf(str_active, index + 1, "%s\n", temp);
printf("String before first digit.: %s\n", str_active);
return 0;
}
I'm wondering if I could do the same with less instructions, so in a better way.

The function strcspn can do it for you:
The strcspn() function calculates the length of the initial segment of s which consists entirely of bytes not in reject.
#include <stdio.h>
#include <string.h>
int main() {
char temp[128] = {0};
char str_active[128] = {0};
sprintf(temp, "%s", "AB01");
printf("Complete string.: %s\n", temp);
strncpy(str_active, temp, strcspn(temp, "0123456789"));
printf("String before first digit.: %s\n", str_active);
return 0;
}

Related

C program that replace word in sentence to another word

I tried to replace a target word in sentence to another word but it doesn't work. Can you please help me with where I got wrong? It has a problem with strstr and strncopy. It says that *swap can be zero, which then makes strncpy stop. I tried to find way to solve this problem, but I couldn't. How can I fix this code?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *swap (char* data, const char* original, const char* change);
int main() {
char string[100];
char original[100];
char change[100];
printf("Input String : ");
fgets(string, 100, stdin);
printf("Find String : ");
fgets(original, 100, stdin);
printf("Replace String : ");
fgets(change, 100, stdin);
printf("%s", swap(string, change, original));
return 0;
}
char *swap(char* data, const char* original, const char* change) {
char* swap;
swap = strstr(data, original);
int num = strlen(change);
if (num == 0 || swap==0) return 0;
strncpy(swap, change, strlen(change));
printf("Result : %s", data);
return 0;
}
I have fixed your code and added a few tests to avoid buffer overflow vulnerability in your swap function.
My version take car of change and original being of different lengths.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *swap(char* data, int size, const char* original, const char* change);
int main()
{
char string[100];
char original[100];
char change[100];
printf("Input String : ");
fgets(string, sizeof(string), stdin);
string[strcspn(string, "\r\n")] = 0; // Remove EOL
printf("Find String : ");
fgets(original, sizeof(original), stdin);
original[strcspn(original, "\r\n")] = 0; // Remove EOL
printf("Replace String : ");
fgets(change, sizeof(change), stdin);
change[strcspn(change, "\r\n")] = 0; // Remove EOL
printf("%s\n", swap(string, sizeof(string), original, change));
return 0;
}
char *swap(char* data, int size, const char* original, const char* change)
{
if ((data == NULL) || (original == NULL) || (change == NULL))
return data; // Unspecified data
int datLen = strlen(data);
int oriLen = strlen(original);
if (oriLen == 0)
return data; // No original specified
char *swap = strstr(data, original);
if (swap == NULL)
return data; // Original not found in data
int chgLen = strlen(change);
if (size < (datLen + chgLen - oriLen))
return data; // Not enough space to store result
if (chgLen != oriLen)
memmove(swap + chgLen, swap + oriLen, 1 + datLen + oriLen - (swap - data));
memmove(swap, change, chgLen);
return data;
}
I have not changed that, but I think it is better to have swap return 0 or 1 if the swap took place or not. Returning data is not very useful as the swap is done in place.

Stack Overflow Error when using string length to a string pointer

Currently creating a C program to reverse a name with the use of pointers and a function. I get a stack overflow error when attempting to use strlen() on char *name. I have not fully created the function yet as I'm currently hitting this problem with strlen().
#include <stdio.h>
#include <string.h>
void format_name();
int main(void)
{
char str[256+1];
char *name = &str[0];
printf("Enter the first and last name: ");
scanf("%[^\n]s", str);
printf("formatting name\n");
format_name (*name);
printf("Formatted name: %s\n", str);
return 0;
}
void format_name (char *name)
{
int spacepos = 0;
printf("Finding string length");
int length = strlen(name);
printf("Size of string = %d", length);
for(p = 0; p <= length - 1; p++)
{
printf("Checking position %d", p);
if(name[p] == ' ' && spacepos == 0)
{
spacepos = p;
printf("first space found at pos %d", p);
}
}
}

Construct String in C

Here is the demo code I am using to construct string from char arrays, Is there any better way to construct String *RV200# *FV200# ??
int main()
{
char String4H1[10] = "*FV";
char String4H3[10] = "*RV";
char String4H2[10] = "#";
char data1[10];
char data2[10];
snprintf(data1,4, "%03d", 200); //Convert integer to string function
snprintf(data2,4, "%03d", 200); //Convert integer to string function
ConvertToString(String4H1,data1, 3); //*FV200
ConvertToString(String4H3,data2, 3); //*RV200
ConvertToString(String4H1,String4H2,6); //*FV200#
ConvertToString(String4H3,String4H2,6); //*RV200#
//Display String4H1 And String 4H3
}
void ConvertToString(char subject[], const char insert[], int pos)
{
char buf[100] = {};
strncpy(buf, subject, pos); // copy at most first pos characters
int len = strlen(buf);
strcpy(buf+len, insert); // copy all of insert[] at the end
len += strlen(insert); // increase the length by length of insert[]
strcpy(buf+len, subject+pos); // copy the rest
strcpy(subject, buf); // copy it back to subject
// deallocate buf[] here, if used malloc()
}
The number 200 is not known at the start of the program, it is fetched from memory using the IDE function to get value from particular memory address.
like this :-
unsigned short BUF = GetWord(#FrontVIB#,0);
unsigned short BUF1 = GetWord(#RearVIB#,0);
//BUF and BUF1 stores the value of address #FrontVIB# and #RearVIB# respectively
**structure** :-
unsigned short GetWord( #Address Alias#, Address Offset );
That's a simple example. Probably I'll be down-voted :)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
bool concatenateString(char **dest, size_t *size, char *stringToAdd)
{
bool retVal = true;
char *dest_old = *dest;
*size += strlen(stringToAdd);
if (*dest == NULL)
{
*size += 1; // to add null terminator of string
*dest = calloc(1, size);
}
else
{
*dest = realloc(*dest, size);
}
if (dest == NULL)
{
free(dest_old);
retVal = false;
}
else
{
strcat(*dest, stringToAdd);
}
return retVal;
}
int main()
{
char newString[32] = {0};
int number;
size_t size = 0;
char *data1 = NULL;
printf("Insert a string:");
scanf(" %s", newString);
if (concatenateString(&data1, &size, newString))
{
printf("Insert a number:");
scanf(" %d", &number);
sprintf(newString, "%03d", number);
if (concatenateString(&data1, &size, newString) )
{
printf("Insert a string:");
scanf(" %s", newString);
if (concatenateString(&data1, &size, newString))
printf("%s\n", data1);
}
}
free(data1);
}
Without using dynamic allocation
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
bool concatenateString(char *dest, size_t size_of_dest, char *stringToAdd)
{
bool retVal = true;
size_t new_size = strlen(dest) + strlen(stringToAdd);
if (new_size < size_of_dest)
{
strcat(dest, stringToAdd);
}
else
{
retVal = false;
}
return retVal;
}
int main()
{
char result[128] = {0};
char newString[32] = {0};
int number;
printf("Insert a string:");
scanf(" %s", newString);
printf("%s\n", newString);
if (concatenateString(result, sizeof(result), newString))
{
printf("Insert a number:");
scanf(" %d", &number);
sprintf(newString, "%03d", number);
if (concatenateString(result, sizeof(result), newString) )
{
printf("Insert a string:");
scanf(" %s", newString);
if (concatenateString(result, sizeof(result), newString))
printf("%s\n", result);
}
}
}
INPUT
Insert a string: *RV
Insert a number: 200
Insert a string: #
OUTPUT
*RV200#
A number of issues, I am only tackling ConvertToString()
Although some attempts made at coping with string buffer issues, too many holes exist in OP's code. Consider the following.
void ConvertToString(char subject[], const char insert[], int pos) {
char buf[100] = {};
strncpy(buf, subject, pos); // copy at most first pos characters
int len = strlen(buf);
...
What is the impact of pos == 100?
strlen(buf) may attempt to find the length of a character array with no null character --> UB.
What is the impact of pos > 100?
strncpy() attempts to write data outside the bonds of buf.
Pedantic: What is the impact of pos < 0?
strncpy() attempts to write data outside the bonds of buf as pos is converted into an excessive large unsigned number.
Concerning strcpy(buf+len, subject+pos);
What is the impact if pos exceeds strlen(subject)
UB as code attempts to read outside subject.
Re-write attempt. The key elements: include the size available for the expanded subject is passed in and determine string lengths. Then test for acceptability. After all that, shift the end of subject to make room for insert.
void ConvertToString(char subject[], size_t subject_size, const char *insert,
size_t pos) {
size_t insert_length = strlen(insert);
size_t subject_length = strlen(subject);
// Insure pos does not exceed subject_length,
// this critical part missing in OP code
if (pos > subject_length) {
pos = subject_length;
}
// Insure we have enough space
size_t buf_size = subject_length + insert_length + 1;
if (buf_size > subject_size) {
Handle_Insufficent_subject_size();
return;
}
// Move end portion of `subject` over to the right `insert_length` places.
memmove(subject + pos + insert_length, subject + pos, subject_length - pos + 1);
memcpy(subject + pos, insert, insert_length); // copy insert
}

conflicting types for function returning a char array

Here's my code:
#include <stdio.h>
#include <string.h>
char input_buffer[1000];
void get_substring(){
int i;
int length;
printf("Please enter a string:\n");
scanf("%[^\n]s", input_buffer);
printf("Index of first character of substring:\n");
scanf("%d", &i);
printf("Length of substring:\n");
scanf("%d", &length);
printf("Substring is %.*s ", length, input_buffer + i);
}
int main(void) {
// your code goes here
//get_substring(0,4);
get_substring();
return 0;
}
That's my current code, I want to return a pointer of the input, instead of just displaying the substring. Sorry for the confusion everyone.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* getSubstring(char* str,size_t start, size_t length)
{
// determine that we are not out of bounds
if(start + length > strlen(str))
return NULL;
// reserve enough space for the substring
char *subString = malloc(sizeof(char) * length);
// copy data from source string to the destination by incremting the
// position as much as start is giving us
strncpy(subString, str + start, length);
// return the string
return subString;
}
int main(int argc, char* argv[])
{
char *str = "Hallo Welt!";
char *subStr = getSubstring(str,0,20);
if(subStr != NULL)
{
printf("%s\n",subStr);
free(subStr);
}
}
This solution should give you a hint how you would start with such a problem.

string operations - weird characters

Description:
I read userinput (e.g "ls -l /") with fgets() and invoke Parse() where it gets seperated ("ls" "-l" "\") for later usage.
The Problem is: the tokens from the the first cycle have weird characters(screenshot below) in it, but from thereon the output is fine.
I tried to initialize both Buffers with zeroes with no change in behaviour. Please explain what is happening in my first output.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/times.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
typedef char* string;
char inputBuffer[512];
string parse[256];
int j,parseCount;
void Parse(void);
void Parse(void)
{
char buffer[512];
string token;
token = " ";
strcpy(buffer, inputBuffer);
j=0;
parse[j] = strtok (buffer, token);
while (parse[j] != NULL)
{
j++;
parse[j] = strtok (NULL, token);
}
parseCount =j;
}
int main (void)
{
printf(">> ");
fgets(inputBuffer, 512, stdin); /* input buffer, max.Input(char), whereFrom?*/
Parse();
for (j=0;j<parseCount;j++){
printf("[%d] %s\n",j, parse[j]);
}
return main();
}
This line
parse[j] = strtok (buffer, token);
stores memory addresses in buffer, which is local to Parse(). The memory representing buffer is invalidated upon the return of Parse(), so also the addresses stored in parse aren't valid anymore when trying to be dereferenced to print what they refer to.
To fix this have the calling function create a temporary working buffer and pass down to `Parse() a reference to it:
char * parse[256] = 0;
char buffer[512] = "";
size_t parseCount = 0;
void Parse(char * buffer)
{
const char * token = " ";
size_t j = 0;
parse[j] = strtok(buffer, token);
while (parse[j] != NULL)
{
j++;
parse[j] = strtok(NULL, token);
}
parseCount = j;
}
int main(void)
{
fgets(buffer, 512, stdin);
{
char buffer_tmp[512];
strcpy(buffer_tmp, buffer);
Parse(buffer_tmp);
for (size_t j = 0; j < parseCount; j++)
{
printf("[%zu] %s\n", j, parse[j]);
}
}
return 0;
}
As I don't like the globals, I'd prefer the following:
#include <stdio.h>
#include <string.h>
size_t parse(char * buffer, char ** parse)
{
const char * token = " ";
size_t j = 0;
parse[j] = strtok(buffer, token);
while (parse[j] != NULL)
{
j++;
parse[j] = strtok(NULL, token);
}
return j;
}
#define IN_MAX (512 + 1 + 1)
int main(void)
{
char buffer[IN_MAX] = "";
if (NULL != fgets(buffer, IN_MAX, stdin))
{
char buffer_tmp[IN_MAX];
strcpy(buffer_tmp, buffer);
{
size_t parse_count = 0;
char * parse[IN_MAX/2 + 1] = 0;
size_t parse_count = parse(buffer_tmp, parse);
for (size_t j = 0; j < parse_count; j++)
{
printf("[%zu] %s\n", j, parse[j]);
}
}
}
else if (ferror())
{
fprintf(stderr, "Error reading from inout stream.\n");
}
return 0;
}

Resources