Getting the first 10 characters of a string? - c

I have not been able to find any information with a web-search. Where should I be looking?

char myString[256]; // Input string
char dest[256]; // Destination string
strncpy(dest, myString, 10);
dest[10] = 0; // null terminate destination

char source[] = "abcdefthijklmn";
char target[100];
strncpy(target, source, 10);
target[10] = '\0'; // IMPORTANT!

Adding to the above answers:
char* someString = "your string goes here";
int main()
{
int n = 10;
printf("(%.*s)\n", n, someString);
return 0;
}

There are many different ways to achieve your goal:
You can use snprintf (safest):
char source[] = "abcdefthijklmn";
char target[100];
snprintf(target, sizeof target, "%.10s", source);
You can use strncat if you know the destination has at least 11 elements:
char source[] = "abcdefthijklmn";
char target[100];
*target = '\0';
strncat(target, source, 10);
You can use strlen and memcpy (same assumption about the size of destination):
char source[] = "abcdefthijklmn";
char target[100];
size_t len = strlen(source);
if (len > 10)
len = 10;
memcpy(target, source, len);
target[len] = '\0';
You can use a loop (same assumption about the size of destination):
char source[] = "abcdefthijklmn";
char target[100];
size_t i;
for (i = 0; i < 10; i++) {
target[i] = source[i];
}
target[i] = '\0';
You could but should not use strncpy()

If you're looking for a good source, here's an example of an online man page you can use:
http://linux.die.net/man/3/strncpy
Important to note: you could also use memcpy instead of strncpy, but it requires you to add your own null-terminating byte.
Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.
Hence, memcpy and strncpy work almost the same here, and memcpy is more efficient and less prone to error.

I got it to work like this.
# include <stdio.h>
# include <string.h>
//Strings. String lenght terminator.
//KHO2016.no1. mingw (TDM-GCC-32) . c-ansi .
int main ()
{
//declare
char src_str[20],dst_str[10];
//valuate
printf ("Enter a sentance of 20 letters\n");
gets (src_str);
strcpy (dst_str,src_str);
//calculate
dst_str [10] ='\0'; // from the "www.stack overflow"
printf ("%s",dst_str);
printf ("\n");
//terminate
return 0;
}

You can also use sprintf with .10 precision format:
#include <stdio.h>
#include <string.h>
int main(void)
{
char source[] = "abcdefghijklmnopqrstuvwxyz";
char dest[11];
memset(dest, '\0', sizeof(dest));
sprintf(dest, "%.10s", source);
printf("%s", dest); // abcdefghij
return 0;
}

Related

cast a char into a char* in C

I have a char array s[11]="0123456789"; and I want to be able to take each digit s[i](using a for loop) and cast it somehow to a char*(I need a char* specifically because I need to use strncat on some other string)
I've been trying to do this for the past 4 hours and I couldn't get anything done.
Unless you're willing to temporarily modify s, or copy the character somewhere else... You're going to have a hard time.
Modify s temporarily.
int main() {
char s[11] = "0123456789";
for (int i = 0; i < strlen(s); i++) {
// Modify s in place.
const char tmp = s[i+1];
s[i+1] = '\0';
char *substr = &s[i];
// Do something with substr.
printf("%s\n", substr);
// Fix s
s[i+1] = tmp;
}
}
Or copy s[i] to a new string.
int main() {
char s[11] = "0123456789";
for (int i = 0; i < strlen(s); i++) {
// Create a temporary string
char substr[2];
substr[0] = s[i];
substr[1] = '\0';
// Do something with substr.
printf("%s\n", substr);
}
}
Or maybe just don't use strncat?
Assuming you're actually using strncat or similar... Those functions are pretty trivial, especially if you are appending only a single character. You might just create your own version.
void append_character(char *buffer, int buffer_size, char new_character) {
int length = strlen(buffer);
if (length + 2 < buffer_size) {
buffer[length] = new_character;
buffer[length+1] = '\0';
} else {
// No space for an additional character, drop it like strncat would.
}
}
Or you could do it as a simple wrapper around strncat:
void append_character(char *buffer, int buffer_size, char new_character) {
char new_string[2] = { new_character, '\0' };
strncat(buffer, buffer_size, new_string);
}
What you are requesting does not make any sense. A char is a small number. A pointer is the address of some memory. Converting a char to a pointer won't give you a valid pointer, but a pointer that will crash as soon as it is used.
For strncat, you need an array of characters containing a C string. You could create a string by writing char array[2]; (now you have an array with space for two characters), then array[0] = whateverchar; array[1] = 0; and now you have a C string with space for exactly one char and one trailing zero byte.
Yet another idea:
#include <stdio.h>
#include <string.h>
int main(void)
{
char src[11]="0123456789";
char dest[50]="abc";
char* p = src;
int i = 0;
int len = strlen(src);
for (i = 0; i < len; i++)
{
strncat(dest,p,1);
p++;
}
printf("src: %s\n", src);
printf("dest: %s\n", dest);
return 0;
}
Compiled with gcc under Ubuntu:
$ gcc hello_str.c -o hello_str
Output:
$ ./hello_str
src: 0123456789
dest: abc0123456789

C - copy the last characters from an unknown length string

In C programming, suppose that I have some input strings with unknown length like:
abcde.xxx
abc.xxx
abcdefgh.xxx
....
How can I take the last 4 characters from them? I tried this way but it doesn't work:
char dest[] = "abcdef.ghi";
char s[5];
memset(s, '\n', sizeof s);
strncpy(s, dest - 5, 4);
But I can't use strstr() since the dest may be wrong with the format xxxx.xxx like abcd.xxxy
char s[5] = {0};
size_t len = 0;
char dest[] = "abcdef.ghi";
char *p = strchr(dest, '.');
if(!p)
{
// error no '.'
return;
}
len = strlen(p);
if(len != sizeof(s)-1)
{
// More or less than 3 characters plus '.'
return;
}
strcpy(s, p);
When the string is null-terminated you can use strlen to get the lenght of the string:
char s[5];
size_t len, offset;
char dest[] = "abcdef.ghi";
len = strlen(dest);
memset( s, '\0', sizeof(char)*5);
offset = len-4;
strncpy( s, &dest[offset], 4 );
If this is not the case you can loop over the string as an array and look for your dot.
Afterwards you can use this index to calculate your correct offset. But be careful for that solution. If one string does not hate a dt and last free character you can cause an access violation.

Separating a string into smaller strings

I have the following string abcd1234 and I want to find a way to break this string into two different strings, abcd and 1234. I have tried the following code:
char buf[100],*str1,*str2;
int x;
fgets(buf,sizeof(buf),stdin);
str1=strtok(buf,"0123456789 \t\n");
str2=strtok(NULL," \n\t\0");
puts(str1);
puts(str2);
x=atoi(str2);
printf("x=%d", x);
but output is abcd 234. And if I try it with one letter and one number, e.g a2 I take only e on output and x is 0.
As per the man page of strtok()
Each call to strtok() returns a pointer to a null-terminated string containing the next token. This string does not include the delimiting byte. [...]
So, while using "0123456789 \t\n" as the delimiter for the first time, 1 will be treated as the actual delimiter and will not be considered in the subsequent parsing.
You may want to use strcspn() and/or strpbrk() to find out the index for the required sub-strings and parse accordingly.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
size_t extract(const char **sp, char *out, int (*test)(int ch));
int main(void){
char buf[100], str1[100], str2[100];
int x;
const char *p = buf;
//size_t len;
fgets(buf, sizeof(buf), stdin);
while(*p){
if(isalpha((unsigned char)*p)){
extract(&p, str1, isalpha);
puts(str1);
} else if(isdigit((unsigned char)*p)){
extract(&p, str2, isdigit);
x = atoi(str2);
printf("%s, x=%d\n", str2, x);
} else {
++p;//skip one char
}
}
return 0;
}
size_t extract(const char **sp, char *out, int (*test)(int ch)){
const char *p = *sp;
while(*p && test((unsigned char)*p)){
*out++ = *p++;
}
*out = '\0';
size_t len = p - *sp;
*sp = p;
return len;
}
Try below code.Hope this will help you.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char string[]="abcd1234";
char digitStr[10];
char charStr[10];
int i,j = 0,k = 0;
for(i=0;string[i];i++)
{
if(isdigit(string[i]))
{
charStr[j++]=string[i];
}
else
{
digitStr[k++]=string[i];
}
}
charStr[j] = '\0';
digitStr[k] = '\0';
printf("%s %s\n",digitStr,charStr);
}
I realize I'm very late on this one, but this is for if anyone has a similar case
Assuming all input strings are like your example, this method will work.
char buf[100];
fgets(buf, sizeof(buf), stdin);
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
int x = atoi(strpbrk(buf, "0123456789"));
char letters[number - buf + 1];
memcpy(letters, sizeof(letters) - 1, buf);
letters[sizeof(letters) - 1] = '\0';
//letters is the word
//x is the number as an int, not a string
• Note the if statement after the fgets. This checks that the newline character was read by fgets, and turns it into a NUL character. (essentially truncating the string).
• As for strpbrk(), that's just a function that returns a pointer to the first occurence of any character in the second string inside the first string. I use it here to find the start of the digit sequence.
• I would also drop the atoi() for strtol() for safety.
• The letters[] array size is the return of strpbrk() (the address of the first number), minus the start of the array (giving the length of the letter string in bytes), plus one for the NUL character I add later.

Displaying output with strncopy

I begin with C and I have to write a method that returns each word in a sentence separated by a whitespace.
So far I have this:
#include<stdio.h>
#include<string.h>
#define SIZE 100
int nextToken(char const * str, int* from, int* len);
int main(){
char str[SIZE+1];
char mot[SIZE+1];
if(fgets(str, SIZE, stdin) == NULL){
puts("Error");
return -1;
}
str[SIZE] = '\0';
int from = 0;
int len = 0;
while(nextToken(str, &from, &len)){
strncpy(mot, &(str[from]), len);
mot[SIZE] = '\0';
printf("'%s'\n", mot);
return 0;
}
return 0;
}
int nextToken(char const * str, int* from, int* len){
*from = 1;
*len = 2;
return 1;
}
I know the return 0 in the while but it's just to run it one time.
So in the nextToken function, when changing the value pointed by len to 1, I get the expected output for the input hello, i.e 'e'.
But when changing the value pointed by len to 2, I was expecting to get 'el' but I get 'el¿■('.
Why do I have this output, why it doesn't print 'el'?
Sorry if it's stupid but I don't know why this is happening as I begin. I'm compiling in C89.
strncpy does not copy a null-terminator in case it copies len characters. In that eventuality you need to ensure that the string is null-terminated explicitly.
Frankly, I don't think that strncpy is really the right function for you to use here.
I'd write it like this:
memcpy(mot, str+from, len);
mot[len] = '\0';
And you'd want to include a check that this did not result in a buffer overrun.

How to concatenate two strings where the source string should be appended before the destination string?

I'm stuck at yet another C problem. How can I concatenate two strings with the second string being inserted before the first string?
This is what I came up with. Unfortunately I'm stuck at all these pointer to chars, char arrays et cetera.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[] )
{
char* output;
int i;
for(i = 9; i > 0; i--)
{
unsigned int value = (unsigned int)i;
char buffer[20];
sprintf(buffer, "%u", value);
// strcat(ouput, buffer); // append before the string.
// first loop: 9
// second loop: 89
// third loop: 789
}
printf("%s", output);
}
How must I correct my code to make it work? I guess I have to somehow set the output variable to empty. When do I need fixed widths for the char array or the pointer? 20 was just a random guess from me.
I'm very confused, as your posted code has absolutely nothing to do with the problem you state. (Well, they both use strings, but that's about it)
char* src = "Hello, ";
char* dest = "World!";
char* temp;
temp = malloc(strlen(src) +strlen(dest) + 1);
strcpy(temp, src);
strcat(temp, dest);
dest = temp;
Unless dest is a fixed buffer of adequate size for the combined string. If so, then replace the last line with:
strcpy(dest, temp);
free(temp);
Now, if you want to specifically build the list of digits backwards, let's try a different tack:
char buffer[10];
buffer[9] = '\0'; // null terminate our string.
char* output;
int i;
for(i = 9; i > 0; i--)
{
// this is a fast way of saying, sprintf("%u", i);
// works only for single digits
char d = (char)('0' + i);
buffer[i-1] = d;
output = &buffer[i-1];
printf("%s", output);
}
Usually, you should just avoid the situation to start with. The most obvious solution for your example would be to simply count upward to start with. When that's not suitable, a recursive solution to reverse the order in which the string is built can still allow you to generate the string from beginning to end:
int build_string(int value, char *string) {
char temp[10];
if (value > -1)
build_string(value-1, string);
sprintf(temp, "%d", value); // use snprintf if available.
strcat(string, temp);
return string;
}
int main() {
char result[20] = {0};
build_string(9, result);
printf("%s", result);
return 0;
}
You can append the integer at the end of the string as:
int i;
char buffer[20];
for(i = 0; i < 10; i++) {
sprintf(buffer+i, "%u", i);
}
printf("%s", buffer); // prints 0123456789
For your stated problem (insert one string in front of another), this code will do the job - but has no error checking. It assumes there is enough space in the target buffer for the existing string and the new prefix:
/* Insert string t in front of string s in string s */
char *strinsert(char *s, const char *t)
{
char *p = s + strlen(s);
char *q = p + strlen(t);
char *r = s;
while (p >= s)
*q-- = *p--;
while (*t)
*s++ = *t++;
return(r);
}
What it does is copy the existing string up by the correct number of places so that there is space for the new string at the beginning.
Assuming that the destination buffer is big enough and that the source and destination do not overlap:
// not sure what order to put the params - the usual C way is destination
// followed by source, but it's also potentially confusing that the result of
// prepend(foo,bar) is "<bar><foo>".
char* prepend(char *restrict dest, const char *restrict src) {
size_t len = strlen(src);
memmove(dest + len, dest, strlen(dest));
return memcpy(dest, src, len);
}
If the buffers may overlap (for example, if src is the second half of dest), this approach doesn't work.
If the destination buffer is not big enough, then someone has to allocate new memory for the result, in which case the question of which is the "source" and which the "destination" disappears - they're both "source" and neither is "destination".

Resources