copying string by incrementing array in c - c

I am trying to search particular element in an array and copying to other.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main()
{
unsigned char a[16] = "1011\n23578A23\n\r";
unsigned char b[9];
unsigned char c[5];
unsigned char d[5] = "1011";
int i = 4;
memcpy(c,a,4);
printf("%s\n", c);
if(strcmp(c,d) == 0)
{
printf("\nEnter\n");
while(a[i] != '\r')
{
if(a[i] == '\n')
{
i = i+1;
printf("start copying\n");
memcpy(b,&a[i],8);
}
i = i+8;
}
}
}
But i am getting seg fault. Is my idea of increment is wrong?

You have to set the null terminator in c string.
memcpy(c,a,3);
c[4] = 0;
printf("%s\n", c);

#include <stdio.h>
#include <string.h>
int main(){
unsigned char a[16] = "1011\n23578A23\n\r";
unsigned char b[9] = {0};
unsigned char c[5] = {0};
unsigned char d[5] = "1011";
int i = 4;
memcpy(c,a,4);
printf("%s\n", c);
if(strcmp(c,d) == 0){
printf("\nEnter\n");
if(a[i] == '\n'){
i = i + 1;
printf("start copying\n");
memcpy(b, &a[i],8);
//printf("%s\n", b);
//i = i + 8;
}
}
}

Related

C string manipulation for removing xx:xx:xx:xx:xx:xx

I have a problem removing a substring xx:xx:xx:xx:xx:xx from one main string. Here is the background info for the problem:
in a function void funA():
void funA(const char* sth){
if (sth == THINGA){
// do A;
}
else if (sth == THINGB){
// do B;
}
eles{
// do C;
}
log_status("current status: - %s", sth);
}
sth is a string contains a substring in the format of xx:xx:xx:xx:xx:xx where x is either a number or a letter. The substring has a space in front of it but might not have one at the end of the string. I need to obfuscate this substring with a *. Since only the substring has :, I made a helper function to locate the first : and the last : and remove 2 characters before it. Delete the last 2 characters and append a *. I think this way is most the best solution. So I'm wondering if there are any more efficient design of a helper function aka a helper function has shorter runtime and uses less memory. Since the substring xx:xx:xx:xx:xx:xx has a very distinguish format, the only easier way I can think of is to do a string match to find the substring and then replace it with a *. I'm open to other more innovative way though.
#ifndef PARSER_STACK_H_INCLUDED
#define PARSER_STACK_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PATTERN_LEN 18
typedef struct{
unsigned int start;
unsigned int finish;
}index;
void remove_str_pattern(char *original, char *extract, unsigned int start, unsigned int finish);
void splitter(char *x, index *index_SF);
unsigned int count_points(const char *x);
void obscure(char *str, index index_SF);
char* return_obscure_string(char *str);
char* return_pattern(char *str);
char* return_pattern(char *str){
index index_SF = {0,0};
char *str_export = calloc(PATTERN_LEN, sizeof(char));
char *tmp = calloc(sizeof(str)/sizeof(char), sizeof(char));
strcpy(tmp, str);
splitter(str, &index_SF);
obscure(tmp, index_SF);
remove_str_pattern(str, str_export, index_SF.start, index_SF.finish);
return str_export;
}
char* return_obscure_string(char *str){
index index_SF = {0,0};
char *str_export = calloc(PATTERN_LEN, sizeof(char));
char *tmp = calloc(sizeof(str)/sizeof(char), sizeof(char));
strcpy(tmp, str);
splitter(str, &index_SF);
obscure(tmp, index_SF);
remove_str_pattern(str, str_export, index_SF.start, index_SF.finish);
return tmp;
}
void obscure(char *str, index index_SF){
for(unsigned int i = index_SF.start; i < index_SF.finish+1; ++i){
if(str[i] != ':'){
str[i] = '*';
}
}
}
void splitter(char *x, index *index_SF){
for(unsigned int i = 0, tmp = 0; i < strlen(x); ++i){
if(x[i] == ':'){
++tmp;
if(tmp == 1){
index_SF->start = i-2;
}else{
if(tmp == 5){
index_SF->finish = i+2;
}
}
}
}
}
unsigned int count_points(const char *x){
int c = 1;
for(unsigned int i = 0; i < strlen(x); ++i){
if((x[i] == ':' && x[i+2] == ':') || (x[i] == ':' && x[i-2] == ':')){
++c;
}
}
return c;
}
void remove_str_pattern(char *original, char *extract, unsigned int start, unsigned int finish){
for(unsigned int i = start, j = 0; i < finish+1; ++i, ++j){
extract[j] = original[i];
}
}
#endif // PARSER_STACK_H_INCLUDED
That is my personal header file for your request, create header file with this code and try it ! :D
Two "main" functions of this file are.
1. char* return_obscure_string(char *str);
For return original string with obscured sub-string..
2. char* return_pattern(char *str);
For return pattern value from a string..
Good Luck Man !
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PATTERN_LEN 18
typedef struct{
unsigned int start;
unsigned int finish;
}index;
void remove_str_pattern(char *original, char *extract, unsigned int start, unsigned int finish);
void splitter(char *x, index *index_SF);
unsigned int count_points(const char *x);
void obscure(char *str, index index_SF);
void main(){
index index_SF = {0,0};
char *origin = "this is first try for me in stack aa:bb:22:44:55:66 overflow...";
char *str_export = calloc(PATTERN_LEN, sizeof(char));
char *tmp = calloc(sizeof(origin)/sizeof(char), sizeof(char));
strcpy(tmp, origin);
splitter(origin, &index_SF);
obscure(tmp, index_SF);
remove_str_pattern(origin, str_export, index_SF.start, index_SF.finish);
printf("start index: %u finish index: %u\n", index_SF.start, index_SF.finish);
printf("obscured string %s\n", tmp);
printf("original str: %s\n", origin);
printf("pattern: %s\n", str_export);
}
void obscure(char *str, index index_SF){
for(unsigned int i = index_SF.start; i < index_SF.finish+1; ++i){
if(str[i] != ':'){
str[i] = '*';
}
}
}
void splitter(char *x, index *index_SF){
for(unsigned int i = 0, tmp = 0; i < strlen(x); ++i){
if(x[i] == ':'){
++tmp;
if(tmp == 1){
index_SF->start = i-2;
}else{
if(tmp == 5){
index_SF->finish = i+2;
}
}
}
}
}
unsigned int count_points(const char *x){
int count = 1;
for(unsigned int i = 0; i < strlen(x); ++i){
if((x[i] == ':' && x[i+2] == ':') || (x[i] == ':' && x[i-2] == ':')){
++count;
}
}
return count;
}
void remove_str_pattern(char *original, char *extract, unsigned int start, unsigned int finish){
for(unsigned int i = start, j = 0; i < finish+1; ++i, ++j){
extract[j] = original[i];
}
}

Create function which sorts 2 given sorted strings

Given two sorted strings, I need to merge these strings to one string, and make it sorted.
sort by the ASCII value. for example:
acdty, berz => abcdertyz
My code:
#include <stdio.h>
#include <stdlib.h>
char* PairSortedArrays(char a[], char b[]) {
char* c = (char*)malloc((sizeof(a) + sizeof(b)) * sizeof(char));
int i, aPos = 0, bPos = 0;
for (i = 0; i < sizeof(*c); i++) {
if ((int)(a[aPos]) <= (int)(b[bPos])) {
c[i] = a[aPos];
aPos++;
}
else {
c[i] = b[bPos];
bPos++;
}
}
return c;
}
int main()
{
printf("%s", PairSortedArrays("acdty", "berz"));
return 0;
}
The first problem is with sizeof(a). if I code: printf("%d", sizeof(a)); it prints 8, while I expect it to print 5.
The expression i < sizeof(*c) controling the for loop is the main culprit. The corrected version of your program could be: (I edited the code a bit)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* PairSortedArrays(const char a[], const char b[])
{
size_t i;
const size_t total_len = strlen(a)+strlen(b);
char *c = malloc(total_len + 1);
size_t aPos = 0, bPos = 0;
for (i = 0; i < total_len; i++) {
if (a[aPos] == '\0') {
strcpy(c + i, b + bPos);
break;
}
if (b[bPos] == '\0') {
strcpy(c + i, a + aPos);
break;
}
c[i] = a[aPos] < b[bPos] ? a[aPos++] : b[bPos++];
}
return c;
}
int main()
{
printf("%s\n", PairSortedArrays("acdty", "berz"));
printf("%s\n", PairSortedArrays("az", "ks"));
return 0;
}
The return value of malloc must be checked against NULL in a real program. Also there is a memory leak (easy to fix).
When working with strings in C, you will want to be using strlen() to see how long they are, not sizeof (which merely tells you what the size of a pointer is).
Also note that sizeof(char) is 1 by definition, so there's no need to say "* sizeof(char)" in your malloc
sizeof(a) will return the size of a pointer in this case which will be 8 bytes if you compile for 64 architecture.
you have to either pass the size of each string or loop the string characters until you reach the '\0' if the string is null-terminated.
You should consider using qsort:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare_chars(const void *p1, const void *p2)
{
return *(const char *)p1 - *(const char *)p2;
}
char *PairSortedArrays(char *a, char *b)
{
char *c = malloc(strlen(a)+strlen(b)+1);
strcpy(c, a);
strcat(c, b);
qsort(c, strlen(c), sizeof(char), compare_chars);
return c;
}
int main()
{
printf("%s", PairSortedArrays("acdty", "berz"));
return 0;
}

String length always 0

I am trying to teach myself C,so I am writing a program to see if a string is present at the end of another string.
#include <stdio.h>
#include <stdlib.h>
int containsAtEnd(char *s, char *t);
int strlen(char *s);
int main()
{
char *x = "tacocat";
char *y = "bol";
printf("%d\n", strend(x, y));
getchar();
return 0;
}
int strlen(char *s)
{
int i;
for (i = 0; i != '\0'; ++i)
;
printf("%d", i);
return i;
}
int containsAtEnd(char *s, char *t)
{
int tlen = strlen(*t);
int slen = strlen(*s);
int i = 0;
s += slen - tlen;
while ((*s == *t) && *s != '\0')
i++; s++; t++;
if (i < (tlen-1))
return 0;
else
return 1;
}
Yet, regardless of the strings given in the main function, "001" is always printed, indicating that the length of both the strings in 0 and the second string is present in the first.
Please try if the following code can help you. I would also advice you to use an IDE or an analysis program that tells you about taking pointer from integer without a cast and conditions that are always true (or always false).
#include <stdio.h>
int containsAtEnd(char *s, char *t);
int strlen(char *s);
int strlen(char *s)
{
int i;
for (i = 0; s[i] != '\0'; ++i)
;
printf("%d", i);
return i;
}
int containsAtEnd(char *s, char *t)
{
int tlen = strlen(t);
int slen = strlen(s);
int i = 0;
s += slen - tlen;
while ((*s == *t) && *s != '\0') {
i++; s++; t++;
}
if (i < (tlen-1))
return 0;
else
return 1;
}
int main()
{
char *x = "tacocat";
char *y = "bol";
printf("%d\n", containsAtEnd(x, y));
char *x2 = "foobarbaz";
char *y2 = "bar";
printf("%d\n", containsAtEnd(x2, y2));
getchar();
return 0;
}

Extract all numbers of N digits from a string in C

I want to get all numbers from a specific string but, these numbers could be more than one digit long as (15, 587, ... exc). Here is what I did "my own code":
int firstIndxOfNumb(char* str, int startIndx, int len) {
int i, val;
i = startIndx;
while (str[i] && i < len) {
val = str[i];
if (isdigit(val))
return i;
i++;
}
return -1;
}
int lastIndxOfNumb(char* exp, int len, int indx1){
int i, curr;
for(i = indx1; i < len; i++){
curr = exp[i];
if(!isdigit(curr)){
return --i;
}
}
return 0;
}
int getNumb(char* exp, int len, int* indx1){
int indx2 = lastIndxOfNumb(exp, len, *indx1);
printf("indx1:%d\tindx2:%d\n", *indx1, indx2);
char temp[indx2-*indx1];
strncpy(temp, exp+*indx1, (size_t) (indx2-*indx1+1));
*indx1 = firstIndxOfNumb(exp, indx2+1, len);
return atoi(temp);
}
void main() {
char *s = "())(15*59";
int len = strlen(s);
int indx1;
indx1 = firstIndxOfNumb(s, 0, len);
printf("%d\n", getNumb(s, len, &indx1));
printf("\n%d", getNumb(s, len, &indx1));
}
And the goal is getting the two numbers (15, 59). The first call was okay but, the second is not "infinite-loop" with values index1:7 okay index2:0 isn't okay! Can you help me to make it working .....
The values are printed by printf(..); in getNum(); function ....
getNumb can be simplified as follows.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int getNumb(char **sp){
char *p = *sp;
while(*p && !isdigit((unsigned char)*p))//skip not digit
++p;
if(!*p)
return -1;//not find numbers (Don't include negative numbers as extract numbers)
int ret = strtol(p, &p, 10);
*sp = p;
return ret;
}
int main(void) {
char *s = "())(15*59";
char *sp = s;
printf("%d\n", getNumb(&sp));
printf("%d\n", getNumb(&sp));
}
When it contains a negative number.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
bool getNum(char **sp, int *v /* out */){
char *p = *sp;
while(*p && !isdigit((unsigned char)*p) && (*p!='-' || !isdigit((unsigned char)p[1])) )//skip not number
++p;
if(!*p)
return false;//not find numbers
*v = strtol(p, &p, 10);
*sp = p;
return true;
}
int main(void) {
char *s = "())(15*59+++-123,-2)";
char *sp = s;
int v;
while(getNum(&sp, &v))
printf("%d\n", v);
}

What is wrong with my c code?

I am getting segmentation fault for the code below. To compile I typed gcc -std=c99 -g alphacode.c. This is a problem I am solving from here, and I am not sure what the problem is.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int catchar(char a, char b) {
char a1[2];
a1[1] = a;
a1[0] = b;
return atoi(a1);
}
int processNumber(char *num) {
int size = strlen(num);
int p[size];
if (num[size-1] != 0)
p[size-1] = 1;
else
p[size-1] = 0;
int i;
for (i = size-2; i>=0; i--)
{
if (catchar(num[i], num[i-1]) > 26 ||
catchar(num[i] , num[i-1]) <1 || num[i] == 0)
p[i] = p[i-1];
else
p[i] = p[i-1] + p[i-2];
}
return p[0];
}
int main() {
int bytes_read;
int nbytes = 5000;
char *number;
bytes_read = getline (&number, &nbytes, stdin);
while (bytes_read != -1) {
int out = processNumber(number);
printf("%d\n", out);
bytes_read = getline (&number, &nbytes, stdin);
}
return 0;
}
int catchar(char a, char b) {
char a1[2];
a1[1] = a;
a1[0] = b;
return atoi(a1);
}
atoi() expects a string, and a string must have a '\0' terminator, without it - atoi() will just keep looking until it find '\0', and you might get garbage or segfault - if you are out of your allocated memory.
You should declare your array of size 3, and put '\0' at index 2.
String needs to be null(0) terminated, thus you need array of 3 ( [a][b][\0]).
int catchar(char a, char b)
{
char concat[3] = { a,b,NULL};
return atoi(concat);
}

Resources