Debugger shows wrong value to pointer - c

I have the following code:
#include <iostream>
#include <cstdio>
#include <list>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <limits>
#include <functional>
#include <algorithm>
#include <cmath>
#include <string>
#include <ostream>
#include <sstream>
#include <bitset>
#include <numeric>
#include<fstream>
using namespace std;
char str[] = "this.is.a.test";
char str2[] = "this.is.another.test";
typedef struct
{
size_t count;
char** strings;
} Tokens;
Tokens Tokenize(char* String, char Split)
{
Tokens t;
t.count = 1;
for (size_t i = 0; String[i] != 0; i++)
{
if (String[i] == Split)
t.count++;
}
t.strings =(char**) malloc(sizeof(char*)* t.count);
if (t.count > 0)
t.strings[0] = String;
for (size_t i = 0, j = 1; String[i] != 0; i++)
{
if (String[i] == Split)
{
t.strings[j] = &String[i + 1];
String[i] = 0;
j++;
}
}
return t;
}
int main(void)
{
Tokens t = Tokenize(str, '.');
printf("number of strings: %i\n---\n", t.count);
for (size_t i = 0; i < t.count; i++)
{
printf("%i: %s\n", i, t.strings[i]);
}
free(t.strings);
}
The problem is when I debug the code and especially that line t.strings[j] = &String[i + 1];
In a test case of this.is.a.test
At the first found dot . , it should points to this, but in the debugger it shows the following picture.
enter code here

What the debugger shows is correct at line 55. The assignment has been made, so t.strings[j] points after the dot.
Note that in Tokenize you allocate Tokens t; on the stack and later return this t. That is bad (very bad!). Because t is on the stack, it will be overwritten by the call to printf.
(And although most is C, formally it is C++ as in C you cannot declare a variable in the for initialization, as in for (size_t i = 0;)

Related

get all indexes of all occurances of a substring in a string

i searched online everywhere but i was unable to find a solution that i could implement in my code, i have some limiting factors to take in accounts, the biggest one is: i cannot use pointers to do this, second one is that i cannot edit before the comment
what i have to do is look for the SEC_B sequence in the adn1 string then save the position of it into a int array to then print it something like this:
Found sequence GTC in: 20 62 69 159 167 196
and yes i did count them manually
i have to do the same with the other sequences, but that doesn't matter as long is i can get it working with one, i can then make it work with all the others
so this is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SECUENCIA0 "TGGCGTTTGCAGATTACTGCGTCCCTCACAAGGGTGTGAA"
#define SECUENCIA1 "GCTGTGCATTCGCGGCACAAGAGTCCCGGGTCCCTGTAGC"
#define SECUENCIA2 "TTCACCATCCTGTTGTACCTATCAAACCTACCTACAGCTT"
#define SECUENCIA3 "AGTGAAGGATTATGCGATTGGCGAGCATAGTACCGGCCCG"
#define SECUENCIA4 "TCACACCGTCTCATTGGTGGCCGACCTTGGAACTCCGTCA"
#define SEC_B "GTC"
#define SEC_D "GAT"
#define SEC_K "GT"
int main()
{
char adn1[201];
adn1[0]='\0';
strcat(adn1,SECUENCIA0);
strcat(adn1,SECUENCIA1);
strcat(adn1,SECUENCIA2);
strcat(adn1,SECUENCIA3);
strcat(adn1,SECUENCIA4);
//edit from here
return 0;
}
this solution doesn't involve any explicit pointers (no * anywhere) and doesn't edit the line above the comment, i managed to come up with this solution thanks to the answer of zazz (which he deleted for some reson), here's how i've done it
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SECUENCIA0 "TGGCGTTTGCAGATTACTGCGTCCCTCACAAGGGTGTGAA"
#define SECUENCIA1 "GCTGTGCATTCGCGGCACAAGAGTCCCGGGTCCCTGTAGC"
#define SECUENCIA2 "TTCACCATCCTGTTGTACCTATCAAACCTACCTACAGCTT"
#define SECUENCIA3 "AGTGAAGGATTATGCGATTGGCGAGCATAGTACCGGCCCG"
#define SECUENCIA4 "TCACACCGTCTCATTGGTGGCCGACCTTGGAACTCCGTCA"
#define SEC_B "GTC"
#define SEC_D "GAT"
#define SEC_K "GT"
int main()
{
char adn1[201];
adn1[0]='\0';
strcat(adn1,SECUENCIA0);
strcat(adn1,SECUENCIA1);
strcat(adn1,SECUENCIA2);
strcat(adn1,SECUENCIA3);
strcat(adn1,SECUENCIA4);
//edit below here
printf("---- Búsqueda de secuencias B, D y K dentro del adn1 ------\n");
int PosicionesB[20];
int bs = 0;
int i, l1, l2;
l1 = strlen(adn1);
l2 = strlen(SEC_B);
for(i = 0; i < l1 - l2 + 1; i++) {
if(strstr(adn1 + i, SEC_B) == adn1 + i) {
PosicionesB[bs] = i;
bs++;
i = i + l2 -1;
}
}
printf("Found sequence GTC in:");
for(int i = 0; i < bs;i++){
printf(" %d",PosicionesB[i]);
}
return 0;
}
It's as simple as this:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
void print_indices_substr(const char *str, const char *substr)
{
char *pstr;
printf("Indices: { ");
for (pstr = (char *)str; (pstr = strstr(pstr, substr)) != NULL; pstr = &pstr[1])
printf("%lu, ", (uintptr_t)pstr - (uintptr_t)str);
printf("}\n");
}
Basically, the function strstr returns a pointer to the first occurrence of 'substr' in 'str' or NULL if no occurrence was found. We can use this pointer in a for loop, and the index will be pstr - str, as you can see in the function above. Example:
int main()
{
const char my_string[] = "ABCDABCD";
print_indices_substr(my_string, "ABCD");
return 0;
}
Output:
Indices: { 0, 4, }

Argument type void is incomplete?

My program is supposed to convert a string to lowercase but I keep gettingg this error "Argument type void is incomplete" when trying to convert a string to lowercase and I don't know why. Could anyone explain why this is happening, thanks
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char str[25] ="HELLOWORLD";
void upperToLower(char *str){
for (size_t i = 0; i < strlen(str); ++i) {
printf("%c", tolower((unsigned char) str[i]));
}
}
int main(void) {
upperToLower(str);
printf("%s\n", upperToLower(str));
return 0;
}
OUTPUT
I guess upperToLower is supposed to modify the string in place. Try the following code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char str[25] ="HELLOWORLD";
void upperToLower(char *str){
for (size_t i = 0; i < strlen(str); ++i) {
str[i] = tolower((unsigned char) str[i]);
}
}
int main(void) {
upperToLower(str);
printf("%s\n", str);
return 0;
}
You could also make upperToLower return the pointer that was passed to it (like strcpy does with its first parameter). That allows the the upperToLower call to be done as part of the printf call like this:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char str[25] ="HELLOWORLD";
char *upperToLower(char *str){
for (size_t i = 0; i < strlen(str); ++i) {
str[i] = tolower((unsigned char) str[i]);
}
return str;
}
int main(void) {
printf("%s\n", upperToLower(str));
return 0;
}
The return type of the function upperToLower() is void, so it cannot be used as a value in expressions.
The function upperToLower() prints things inside that, so you won't need to externally print something about that except for the newline character.
Try this:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char str[25] ="HELLOWORLD";
void upperToLower(char *str){
for (size_t i = 0; i < strlen(str); ++i) {
printf("%c", tolower((unsigned char) str[i]));
}
}
int main(void) {
upperToLower(str);
upperToLower(str); /* put this out of printf() */
printf("\n"); /* and print just newline character here */
return 0;
}
Yes. As specified in C specification the type void is an incomplete type.
The void type comprises an empty set of values; it is an incomplete
object type that
cannot be completed.
As result it is not possible to form any value of type void. Pointers of type void* can be used, but they cannot be dereferenced.
Your function returns void, you're literally passing nothing as a parameter.

split char data without delimeter

i have this data
27a1bc
thats supposed to be a data recieved from serial communication/uart.
the question is, is there anyway i could separate this data without delimeter? i need the data change to this
27
a1
bc
is there anyway i could do this without delimeter/strtok?
here is my code, im stuck.
#include <stdio.h>
#include <stdlib.h>
char usart[] = "27a1bc";
int main(void) {
// your code goes here
scanf("%c", usart[1]);
scanf("%c", usart[0]);
return 0; }
You can use a pointer to an array of 3 char's (2 + 1 for the trailing NUL) and memcpy in a loop:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char usart[] = "27a1bc";
int main(void)
{
size_t i, n = sizeof usart / 2;
char (*token)[3];
token = calloc(n, sizeof *token);
if (token == NULL) {
perror("calloc");
exit(EXIT_FAILURE);
}
for (i = 0; i < n; i++) {
memcpy(token[i], usart + (i * 2), 2);
puts(token[i]);
}
free(token);
return 0;
}

Randomize letters in string in C

I have for example "asd" and I want it to be randomized to DAS, DSA, SAD, you know. How can I code this? Tried a few solutions but It didnt really work.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
int main()
{
printf("type in the word\n");
char haslo[128];
scanf("%s", haslo);
char set[128];
char hasloa[128];
strcpy(set, haslo);
unsigned int Ind = 0;
srand(time(NULL) + rand());
int len = strlen(set);
while(Ind < len)
{
hasloa[Ind++] = set[rand()%62];
}
hasloa[len] = '\0';
printf("%s", hasloa);
return 0;
}
Change 62 inside the while loop to "len"

What is wrong with my program reversing strings in C?

I want to create a function to reverse a string in C. I found a couple pre-made on the internet but I wish to create mine. Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* inverseCarac(char* chaine){
if(chaine==0||*chaine==0) return NULL;
int j, i;
int taille=strlen(chaine);
char* inverse=malloc(taille*sizeof(char));
for(j=taille-1, i=0; j>0; j--, i++){
*(inverse+i)=*(chaine-j);
}
return inverse;
}
int main(void){
char* test="bonjour";
char* inv=inverseCarac(test);
printf("%s", inv);
return 0;
}
I can't figure out why I get a segmentation fault.
There were several errors in your code, the most significant being the offset from chaine in the wrong direction. Also, lack of space for a string terminator, and j ending prematurely.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* inverseCarac(char* chaine){
if(chaine==0||*chaine==0) return NULL;
int j, i;
int taille=strlen(chaine);
char* inverse=malloc(taille+1); // add 1 for terminator
for(j=taille-1, i=0; j>=0; j--, i++){ // change j>0 to j >= 0
*(inverse+i)=*(chaine+j); // change -j to +j
}
inverse[taille] = '\0'; // write terminator
return inverse;
}
int main(void){
char* test="bonjour";
char* inv=inverseCarac(test);
printf("%s\n", inv);
return 0;
}
Program output
ruojnob

Resources