C keeles stringide lõikamise juhend | omafunktsioonid, UTF‑8

目次

1. Sissejuhatus

C keeles stringide käsitlemine on üks oluline oskus programmeerimise õppimisel. Eriti on stringide lõikamine (osastringi ekstraheerimine) sageli kasutusel andmete töötlemisel ja vormingu konverteerimisel.

Selles artiklis käsitleme C keeles stringide lõikamise meetodeid, sealhulgas standardraamatukogu funktsioonide kasutamist, oma funktsioonide loomist, mitmebaidiste märkide (jaapani) toetust ning stringide jagamise meetodeid. Samuti tutvustame rakendusnäiteid ja veahaldust, nii et palun lugege lõpuni.

Mis saab selles artiklis õppida

Selle artikli lugemisega omandate järgmised oskused.

  • C keele stringide põhimõtted ja lõppmärgija roll
  • strncpystrchrstandardraamatukogu funktsioonide abil osalise stringi lõikamine
  • Kohandatud funktsioon
  • Mõistes multibaiti märke (jaapani)
  • strtok stringi jagamise meetod
  • Mõnede kindlate märkide ees- ja järelteabe saamise meetod

Selgitame nii, et ka algajatel oleks lihtne mõista, kasutades koodinäiteid.

Miks on C keeles stringide lõikamine oluline?

C keel käsitleb stringe kui massiivi (char tüüpi massiiv), seega ei saa neid nagu teistes kõrgemas tasemes keeltes (Python või JavaScript) lihtsalt osastringiks võtta. Seetõttu on oluline valida sobiv meetod järgmistes olukordades.

1. Sisendandmete töötlemine

Näiteks logiandmete või CSV-failide analüüsi käigus on vaja teatud elemente ekstraheerida.

2. Kindlate võtmesõnade otsimine

Määratud stringist kindlate võtmesõnade otsimine ja nende eel- ja järelinna teabe hankimine on otsingufunktsiooni ja andmete ekstraheerimise jaoks hädavajalik.

3. Programmi turvalisuse parandamine

strncpy kasutades õigesti, saab puhveri ülevoolu (andmete kirjutamine, mis ületab puhvri suuruse) vältida. See on oluline turvariskide vältimiseks.

Artikli struktuur

Selles artiklis käsitleme järgnevat järjekorda.

  1. Mis on C keele string? Baasikonseptsioonid ja lõppmärgise tähtsus
  2. C keeles osalise stringi lõikamise meetod【Standardraamatukogu】
  3. C keeles osalise stringi lõikamise meetod【Kohandatud funktsioonide versioon】
  4. Märgi koodi järgi stringi lõikamise meetod
  5. C keeles stringi jagamise meetod
  6. Rakenduse näide: kindla märgi ees- ja järelmärkide väljavõtmise meetod
  7. kokkuvõte
  8. FAQ

Alustame siis põhjalikult uurides „Mis on C keele stringid? Põhikontseptsioonid ja lõpetavat märki tähtsus“.

2. C gengo stringid? Põhikontseptsioon ja lõpetusmärgi tähtsus

2.1 C gengo stringide põhikontseptsioon

Stringid on “char’i massiiv”

Stringe käsitletakse kui tähemärkide massiivi(char tüüpi massiiv). Näiteks on allolev kood stringi defineerimise ja kuvamise põhiline näide.

#include <stdio.h>

int main() {
    char str[] = "Hello, World!"; // Define a string literal as an array
    printf("%s ", str); // Output the string
    return 0;
}

Selles koodis on "Hello, World!" string salvestatud char tüüpi massiivi ja printf("%s\n", str); abil väljastatud.

Stringide sisemine struktuur

String "Hello" on mälus salvestatud järgmiselt.

indeks012345
tekstHello\0

C gengo lisab automaatselt lõppmärgi (nullmärk '\0') stringi lõppu, seega stringi pikkus on “tegelik tähemärkide arv + 1”.

2.2 Lõppmärgi(nullmärk '

Mis on nullmärk?

'
)tähtsus

Probleemid, kui nullmärki pole

Nullmärk('\0')on stringi lõppu näitav erimärk. C gengo stringide õige käsitlemiseks tuleb mõista selle olemasolu.

#include <stdio.h>

int main() {
    char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; // Explicitly specify the null terminator
    printf("%s ", str);                            // Display correctly
    return 0;
}

Ülaltoodud koodis, kui '\0' puudub, ei tuvastata "Hello" lõppu ja võib tekkida ootamatu käitumine.

2.3 Stringide õige defineerimise meetodid

Nagu allpool näidatud, lõppmärgi unustamine võib põhjustada mälus ebatavalist käitumist.

#include <stdio.h>

int main() {
    char str[5] = {'H', 'e', 'l', 'l', 'o'}; // Does not include the null terminator
    printf("%s ", str);                      // May cause unexpected behavior
    return 0;
}

Vea põhjus

  • printf("%s\n", str);nulli sümboli '\0'
  • Kui pole olemas, võib tekkida, et memori teised andmed väljastatakse.

Meetod ① Stringi literalit kasutades

Meetod ② Määratle massiiv selgesõnaliselt

Kõige levinum stringi defineerimise meetod on stringi literalite kasutamine.

char str[] = "Hello";

Selles meetodis lisab C kompilaator automaatselt nullmärgi '\0' ning eraldi töötlemist ei vaja.

2.4 Kuidas kontrollida stringi suurust

Kui lisad käsitsi '\0' massiivi, kirjuta järgmiselt.

char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
  • Määrake sõnumi pikkuse suurus ja lõpuks on oluline lisada 。
  • Kui sisestada unustame, tekib ootamatu käitumine.

strlen toimimine

Stringi pikkuse (tähemärkide arv) saamiseks kasuta strlen funktsiooni.

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello";
    printf("Length of the string: %lu\n", strlen(str)); // Outputs 5 (does not include the null terminator)
    return 0;
}

2.5 Kokkuvõte

  • strlennulli märgi '\0' ilmumiseni
  • sizeof(str)
侍エンジニア塾

3. C keeles osalise stringi väljavõtmise meetodid (standardraamatukogu)

  1. C keele stringid on char massiivina esitatud
  2. Terminatsioonisümbol (null sümbol '\0') näitab stringi lõppu, seetõttu tuleb see alati kaasata
  3. Tekstijada pikkuse saamiseks strlen kasutades
  4. Kui stringe ei defineeri sobiva viisil, võib tekkida ootamatuid vigu.

3.1 strncpy kasutades osalise stringi hankimine

C keeles osalise stringi väljavõtmiseks on võimalik kasutada standardraamatukogu. Selles jaotises selgitatakse, kuidas kasutada strncpy ja strchr ning teisi standardraamatukogu funktsioone, et stringi osaliselt hankida.

strncpy põhisisend

strncpy on funktsioon, mis kopeerib stringi osa teise puhvri.

Põhilised kasutusnäited

char *strncpy(char *dest, const char *src, size_t n);
  • dest
  • src
  • n'\0'

strncpy tähelepanekud

#include <stdio.h>
#include <string.h>

int main() {
    char src[] = "Hello, World!";
    char dest[6];  // Buffer to store the substring

    strncpy(dest, src, 5); // Copy the first 5 characters "Hello"
    dest[5] = '\0';        // Manually add the null terminator

    printf("Substring: %s\n", dest);  // Output "Hello"

    return 0;
}

3.2 strncpy_s kasutades turvaline stringi kopeerimine

  1. nulli märk '\0' peab lisama käsitsi kopeerib kuni maksimaalselt märki, kuid ei lisa automaatselt selgesõnaliselt lisada.
  2. Hoiatus: buffer overflow suurusest suurem kui võib kirjutada ületades pufferi.

strncpy_s põhisisend

strncpy_s on versioon, mis tugevdab strncpy turvalisust ja võimaldab vältida puhvri ületäitumist.

Kasutusnäide

errno_t strncpy_s(char *dest, rsize_t destsz, const char *src, rsize_t n);
  • dest
  • destszdest
  • src
  • n

strncpy_s eelised

#include <stdio.h>
#include <string.h>

int main() {
    char src[] = "Hello, World!";
    char dest[6];

    if (strncpy_s(dest, sizeof(dest), src, 5) == 0) {
        dest[5] = '\0';  // Add null terminator just in case
        printf("Substring: %s\n", dest);
    } else {
        printf("Copy error\n");
    }

    return 0;
}

3.3 strchr kasutades kindla täheni lõikamine

  • Puhvri suuruse () määramiseks on võimalik turvaliselt kopeerida.
  • destszn

Kuid tuleb märkida, et strncpy_s lisati C11 standardiga, seega ei pruugi see mõnes keskkonnas saadaval olla.

strchr põhisisend

strchr võimaldab leida kindla tähe asukoha ja hankida stringi kuni selle kohani.

Kasutusnäide

char *strchr(const char *str, int c);
  • str
  • cchar

Olulised punktid

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello, World!";
    char *pos = strchr(str, ','); // Find the position of ','

    if (pos != NULL) {
        int length = pos - str; // Calculate the number of characters up to ','
        char result[20];

        strncpy(result, str, length);
        result[length] = '\0'; // Add the null terminator

        printf("Substring: %s\n", result);  // Output "Hello"
    }

    return 0;
}

3.4 strstr kasutades märksõna otsing ja lõikamine

  • strchresimene kord leitud c aadressi tagastab
  • pos - strstrncpy

strstr põhisisend

strstr on kasulik osalise stringi otsimiseks ja sealt edasi oleva stringi hankimiseks.

Kasutusnäide

char *strstr(const char *haystack, const char *needle);
  • haystack
  • needle

Olulised punktid

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello, World!";
    char *pos = strstr(str, "World"); // Search for the position of "World"

    if (pos != NULL) {
        printf("Found substring: %s\n", pos);
    } else {
        printf("Substring not found.\n");
    }

    return 0;
}

3.5 Kokkuvõte

  • strstrneedle
  • NULLneedlehaystack

4. C keeles osalise stringi väljavõtmise meetodid【Omafunktsioonide osa】

  1. strncpy Kui kasutada strncpy, saab osalise stringi turvaliselt kopeerida, kuid nullmärgi tuleb käsitsi lisada。
  2. strncpy_s võimaldab määrata destsz ja suurendab turvalisust。
  3. strchr kasutades saab saada osalise stringi kuni kindla märgi.
  4. strstr kui kasutada seda, saab kindla märksõna asukohta hankida ja sealt edasi lõigata。

Standardraamatukogu kasutamisega saab C keeles stringi töötlemise rakendada lihtsalt ja turvaliselt.

4.1 Enda funktsioonide loomise eelised

Kui kasutada standardraamatukogu, on võimalik teha põhilist osalise stringi väljavõtmist, kuid mõnel juhul on vaja paindlikumat meetodit . Seetõttu selgitame selles sektsioonis, enda funktsioonide kasutamisega osalise stringi väljavõtmise kohta.

4.2 Põhiline osalise stringi väljavõtmise funktsioon

Kui kasutada standardraamatukogu, saab kopeerida ja otsida osalisi stringe, kuid on järgmised probleemid.

  • strncpy ei lisa automaatselt nullmärki '\0'
  • strchr ja strstr on ainult osaline otsing
  • Stringi manipuleerimine on raskam kui paindlik

Seetõttu on kasulik luua enda funktsioon, mida saab kohandada konkreetsete vajaduste järgi.

Funktsiooni spetsifikatsioon

Esmalt loome põhifunktsiooni, mis võtab stringi välja määratud positsioonist.

Rakenduskood

  • argument
  • const char *source
  • int start
  • int length
  • char *dest
  • Töötlemise sisu
  • startlengthdest
  • '\0'

Olulised punktid

#include <stdio.h>
#include <string.h>

void substring(const char *source, int start, int length, char *dest) {
    int i;
    for (i = 0; i < length && source[start + i] != '\0'; i++) {
        dest[i] = source[start + i];
    }
    dest[i] = '\0'; // Add null terminator
}

int main() {
    char text[] = "Hello, World!";
    char result[10];

    substring(text, 7, 5, result); // Extract "World"
    printf("Substring: %s\n", result);

    return 0;
}

4.3 malloc kasutades dünaamilist osalise stringi hankimist

  • forpikkus
  • '\0'
  • dest[i] = '\0';paiguta alati null-merkis lõppu

Funktsiooni spetsifikatsioon

Eelnevas funktsioonis tuleb dest suurus eelnevalt reserveerida. Kui aga vajaliku suuruse saab dünaamiliselt reserveerida, muutub funktsioon üldisemaks.

Rakenduskood

  • Vajalikku mälu abil allokatsioon
  • alguspikkus
  • Kutsuvõtjal tuleb

Olulised punktid

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *substring_dynamic(const char *source, int start, int length) {
    char *dest = (char *)malloc(length + 1); // +1 for the null terminator
    if (dest == NULL) {
        return NULL; // Memory allocation failed
    }

    int i;
    for (i = 0; i < length && source[start + i] != '\0'; i++) {
        dest[i] = source[start + i];
    }
    dest[i] = '\0';

    return dest;
}

int main() {
    char text[] = "Hello, World!";
    char *result = substring_dynamic(text, 7, 5);

    if (result != NULL) {
        printf("Substring: %s\n", result);
        free(result); // Free allocated memory
    } else {
        printf("Memory allocation failed.\n");
    }

    return 0;
}

4.4 Mitme baiti tähemärgid (jaapani keel) tugi

  • mallocdynamiliselt mälestuse allokatsiooni
  • Kasutuse järel on vaja abil mälu vabastada.

Mitme baiti tähemärkide arvestav rakendus

Kui töötada jaapani keelega (UTF-8 jne mitme baiti tähemärkidega), ei pruugi üks märk olla 1 bait, seega lihtne substring funktsioon ei tööta õigesti.

Rakenduskood (UTF-8 tugi)

  • mbstowcswchar_t
  • wcsncpy
  • wcstombs

Olulised punktid

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <locale.h>

void substring_utf8(const char *source, int start, int length, char *dest) {
    setlocale(LC_ALL, ""); // Set the locale

    wchar_t wsource[256];
    mbstowcs(wsource, source, 256); // Convert UTF-8 string to wide-character string

    wchar_t wresult[256];
    wcsncpy(wresult, wsource + start, length); // Extract substring in wide characters
    wresult[length] = L'\0';

    wcstombs(dest, wresult, 256); // Convert back to multibyte string
}

int main() {
    char text[] = "こんにちは、世界!"; // UTF-8 string
    char result[20];

    substring_utf8(text, 5, 3, result); // Extract "世界"
    printf("Substring: %s\n", result);

    return 0;
}

4.5 Kokkuvõte

  • setlocale(LC_ALL, "");
  • mbstowcs
  • wcsncpywcstombs

5. Tekstilõikude meetodid kodeeringu järgi

  1. osa-string Kui ise teha, saad paindlikult osa-stringi hankida。
  2. dynaamiline mälu allokatsioon (malloc) kasutades seda, saab saada muutuvate suurustega osarida。
  3. Kui töötled multibaiti märke (jaapani keeles), kasuta mbstowcs / wcstombs

Kui standardraamatukogu strncpy või strchr ei sobi, saab enda funktsiooni loomisega C keele stringi töötlemist veelgi võimsamaks muuta.

5.1 ASCII (1-bait tähed) puhul

C keeles, kui kodeeringu erinevusi ei võeta arvesse, siis tekstilõikude töötlemine ei tööta õigestivõib juhtuda. Eriti kui käsitletakse mitme baidi tähti nagu jaapani keel (UTF-8, Shift_JIS, EUC-JP jne), siis 1 märk != 1 bait, mistõttu lihtsad strncpy või substring funktsioonidega ei saa seda õigesti töödelda.

Selles sektsioonis, tekstilõikude meetodid kodeeringu järgi kohta üksikasjalikult selgitame.

Põhiline alamsõne hankimine

Rakenduse näide

ASCII tähed on 1 märk = 1 bait seega strncpy või substring funktsioonidega saab hõlpsasti töödelda.

5.2 UTF-8 (mitme baidi tähed) puhul

#include <stdio.h>
#include <string.h>

void substring_ascii(const char *source, int start, int length, char *dest) {
    strncpy(dest, source + start, length);
    dest[length] = '\0'; // Add null terminator
}

int main() {
    char text[] = "Hello, World!";
    char result[6];

    substring_ascii(text, 7, 5, result); // Extract "World"
    printf("Substring: %s\n", result);

    return 0;
}

Olulised punktid

  • Kui tegemist on ASCII tekstiga (ainult ladina tähed ja numbrid), on strncpy piisav
  • '\0'Lisage alati (nulli märk)

UTF-8 omadused

Õige töötlemismeetod

UTF-8-s, 1 tähe baidi arv on 1-4 baiti muutuva, seega lihtsasti strncpy kasutades võib tekkida tähe poole lõikamise oht.

UTF-8-le vastav alamsõne hankimine

C keeles, UTF-8 turvaliseks töötlemiseks mbstowcs kasutades teisendada laiendatud stringiks ( wchar_t) ja alamsõne hankimise meetod on soovitatav.

5.3 Shift_JIS (mitme baidi tähed) puhul

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <locale.h>

void substring_utf8(const char *source, int start, int length, char *dest) {
    setlocale(LC_ALL, ""); // Set the locale

    wchar_t wsource[256];
    mbstowcs(wsource, source, 256); // Convert multibyte string to wide-character string

    wchar_t wresult[256];
    wcsncpy(wresult, wsource + start, length); // Get the substring
    wresult[length] = L'\0';

    wcstombs(dest, wresult, 256); // Convert wide-character string back to multibyte
}

int main() {
    char text[] = "こんにちは、世界!"; // UTF-8 string
    char result[20];

    substring_utf8(text, 5, 3, result); // Extract "世界"
    printf("Substring: %s\n", result);

    return 0;
}

Olulised punktid

  • setlocale(LC_ALL, "");
  • mbstowcswchar_twcsncpy
  • wcstombs

Shift_JIS omadused

Shift_JIS-le vastav alamsõne hankimine

Shift_JIS-s, 1 märk võib olla 1 või 2 baiti seega lihtne strncpy põhjustab märgikodeerimise vigu.

Rakendus Shift_JIS-is

Shift_JIS-i puhul samuti teisendada laiendatud stringiks ja töödelda on soovitatav.

5.4 EUC-JP (mitme baidi tähed) puhul

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <locale.h>

void substring_sjis(const char *source, int start, int length, char *dest) {
    setlocale(LC_ALL, "Japanese"); // Set locale to handle Shift_JIS

    wchar_t wsource[256];
    mbstowcs(wsource, source, 256); // Convert multibyte string (Shift_JIS) to wide-character string

    wchar_t wresult[256];
    wcsncpy(wresult, wsource + start, length); // Extract substring
    wresult[length] = L'\0';

    wcstombs(dest, wresult, 256); // Convert wide-character string back to multibyte (Shift_JIS)
}

int main() {
    char text[] = "こんにちは、世界!"; // Shift_JIS string (depending on environment)
    char result[20];

    substring_sjis(text, 5, 3, result); // Extract "世界"
    printf("Substring: %s\n", result);

    return 0;
}

Olulised punktid

  • Shift_JIS-i õige töötlemiseks seadistada.
  • mbstowcswcstombs

EUC-JP omadused

EUC-JP-le vastav alamsõne hankimine

EUC-JP, nagu ka Shift_JIS, sest ühe tähe baidi arv on erinev, vajab laiendatud tähemärkide kasutamist teisendamiseks .

5.5 Kokkuvõte

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <locale.h>

void substring_eucjp(const char *source, int start, int length, char *dest) {
    setlocale(LC_ALL, "ja_JP.eucJP"); // Set locale to handle EUC-JP

    wchar_t wsource[256];
    mbstowcs(wsource, source, 256); // Convert multibyte string (EUC-JP) to wide-character string

    wchar_t wresult[256];
    wcsncpy(wresult, wsource + start, length); // Extract substring
    wresult[length] = L'\0';

    wcstombs(dest, wresult, 256); // Convert wide-character string back to multibyte (EUC-JP)
}

int main() {
    char text[] = "こんにちは、世界!"; // EUC-JP string (depending on environment)
    char result[20];

    substring_eucjp(text, 5, 3, result); // Extract "世界"
    printf("Substring: %s\n", result);

    return 0;
}

Olulised punktid

  • setlocale(LC_ALL, "ja_JP.eucJP");
  • mbstowcswcstombs

6. C-gengos stringide jagamise meetod

Märgikoodebaidite arvSoovitatud töötlemismeetod
ASCII1 baitstrncpy
UTF-81-4 bytembstowcswcstombs
Shift_JIS1 või 2 baitimbstowcswcstombs
EUC-JP1 või 2 baitimbstowcswcstombs
  • Kui on ainult ASCII tekst strncpy on OK
  • UTF-8, Shift_JIS, EUC-JP puhul kasutage mbstowcs / wcstombs
  • Sõltuvalt keskkonnast setlocale(LC_ALL, \"...\"); sobivalt seadistada

6.1 strtok kasutades stringide jagamine

Stringide jagamise protsess on vajalik paljudes olukordades, CSV-andmete analüüs, käsurea argumentide töötlemine, logiandmete analüüs jne. C-gengos on olemas standardraamatukogu funktsioonid nagu strtok ja strtok_r ning ka võimalus luua oma funktsioon.

Selles sektsioonis selgitame üksikasjalikult, stringide jagamise meetodit kindla eraldusmärgi alusel.

Põhiline süntaks

strtok on funktsioon, mis jaotab stringi määratud eraldusmärgi (delimiteri) alusel.

Kasutusnäide: stringi jagamine komaga ,

char *strtok(char *str, const char *delim);
  • str
  • delim
  • Tagastatud väärtus
  • Tähelepanu kohadstrtok'\0'

Tulemused

#include <stdio.h>
#include <string.h>


int main() {
    char str[] = "apple,banana,orange,grape"; // String to be split
    char *token = strtok(str, ",");            // Get the first token

    while (token != NULL) {
        printf("Token: %s\n", token);
        token = strtok(NULL, ",");             // Get the next token
    }

    return 0;
}

strtok tähelepanekud

token: apple
token: banana
token: orange
token: grape

6.2 strtok_r kasutades thread-safe stringide jagamine

  1. Muuda algset teksti
  • strtokeraldaja märgi '\0' asendamine,
  1. ei ole lõimeohutud
  • strtokglobaalseid staatilisi muutujat

Põhiline süntaks

strtok_r on strtok thread-safe versioon, mis salvestab oleku saveptr muutujasse, võimaldades turvalist kasutamist mitme lõime keskkonnas.

Kasutusnäide: stringi jagamine tühikuga

char *strtok_r(char *str, const char *delim, char **saveptr);
  • str
  • delim
  • saveptr

strtok_r eelised

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello World from C"; // String to be split
    char *token;
    char *saveptr; // Pointer to store internal state

    token = strtok_r(str, " ", &saveptr); // Get the first token
    while (token != NULL) {
        printf("Token: %s\n", token);
        token = strtok_r(NULL, " ", &saveptr); // Get the next token
    }

    return 0;
}

6.3 Oma funktsiooniga stringide jagamine (meetod, mis ei kasuta strtok)

  • lõime turvaline
  • Võib samaaegselt töödelda mitmeid tekste

Oma funktsiooni spetsifikatsioon

strtok muudab algset stringi, seega on võimalik luua oma funktsioon, mis jagab stringi ilma seda muutmata.

Rakenduskood

  • sisend
  • const char *source
  • const char delim
  • char tokens[][50]
  • töötlus
  • source
  • delimtokens

Tulemused

#include <stdio.h>
#include <string.h>

void split_string(const char *source, char delim, char tokens[][50], int *count) {
    int i = 0, j = 0, token_index = 0;

    while (source[i] != '\0') {
        if (source[i] == delim) {
            tokens[token_index][j] = '\0';
            token_index++;
            j = 0;
        } else {
            tokens[token_index][j] = source[i];
            j++;
        }
        i++;
    }
    tokens[token_index][j] = '\0';
    *count = token_index + 1;
}

int main() {
    char text[] = "dog,cat,bird,fish";
    char tokens[10][50]; // Can store up to 10 words
    int count;

    split_string(text, ',', tokens, &count);

    for (int i = 0; i < count; i++) {
        printf("Token: %s\n", tokens[i]);
    }

    return 0;
}

Olulised punktid

Token: dog
Token: cat
Token: bird
Token: fish

6.4 Stringide jagamise rakendused (CSV-andmete töötlemine)

  • source
  • tokens

CSV-andmete analüüsi näide

CSV (komaga eraldatud) andmeid saab analüüsida strtok kasutades.

Tulemused

#include <stdio.h>
#include <string.h>

int main() {
    char csv[] = "Alice,24,Female\nBob,30,Male\nCharlie,28,Male"; // CSV data
    char *line = strtok(csv, "\n"); // Process line by line

    while (line != NULL) {
        char *name = strtok(line, ",");
        char *age = strtok(NULL, ",");
        char *gender = strtok(NULL, ",");

        printf("Name: %s, Age: %s, Gender: %s\n", name, age, gender);

        line = strtok(NULL, "\n");
    }

    return 0;
}

6.5 Kokkuvõte

Name: Alice, Age: 24, Gender: Female
Name: Bob, Age: 30, Gender: Male
Name: Charlie, Age: 28, Gender: Male

Järeldus

meetodeelispuudused
strtoksaab hõlpsasti jagadaAlgselt teksti muutmine
strtok_rlõimeohutKasutamine on natuke keeruline
enda tehtud funktsioonÄra muuda algset tekstikood pikenevad
CSV analüüsandmete töötlemisel mugavstrtok Pange tähele piiranguid

7. Rakenduse näited: Kuidas ekstraheerida kindla tähe eel- ja järeltükid

  • Kui tegemist on lihtsa jagamisega strtok
  • Kui kasutate multiraadiga strtok_r
  • Kui sa ei taha originaali muuta, kasuta ise tehtud funktsiooni
  • CSV-andmete analüüsile ka rakendatav

Järgmises sektsioonis selgitame üksikasjalikult „Rakenduse näide: kindla tähe eel- ja järeltõmbamise meetod”.

7.1 strchr kasutades kindla tähe eelneva stringi hankimine

Tekstide töötlemisel on sageli vaja kindla tähe või märksõna eel- ja järeltükid operatsiooni. Näiteks võib ette tulla järgmised juhtumid.

  • URL-ist ainult domeeni osa hankimine
  • Failinime tõmbamine failitee alt
  • Hangi kindla sildi või sümboli ees ja taga olevad stringid

C keeles saab kasutada strchr ja strstr funktsioone, et selliseid operatsioone teostada. Samuti on võimalik luua omaenda funktsioon, kui on vaja paindlikumat lahendust.

Põhiline süntaks

strchr kasutades saab kindlaks teha kindla tähe (esimese leitud) asukoha.

Kasutusnäide: Failitee kaudu failinime hankimine

char *strchr(const char *str, int c);
  • str
  • cchar

strchr tagastab c asukoha aadressi, kui see leitakse.

Tulemused

#include <stdio.h>
#include <string.h>

void get_filename(const char *path, char *filename) {
    char *pos = strrchr(path, '/'); // Search for the last '/'

    if (pos != NULL) {
        strcpy(filename, pos + 1); // Copy from the character after '/'
    } else {
        strcpy(filename, path); // If no '/', copy the whole path
    }
}

int main() {
    char path[] = "/home/user/documents/report.txt";
    char filename[50];

    get_filename(path, filename);
    printf("Filename: %s\n", filename);

    return 0;
}

Olulised punktid

Filename: report.txt

7.2 strstr kasutades kindla märksõna järeltükki hankimine

  • strrchrviimase esinemise kindlale märgile ( / ) asukohta hankida
  • pos + 1saad ainult faili nime

Põhiline süntaks

strstr kasutades saab kindla stringi (märksõna) otsida ja selle asukohast alates järgneva stringi hankida.

Kasutusnäide: Domeeni hankimine URL-ist

char *strstr(const char *haystack, const char *needle);
  • haystack
  • needle

strstr tagastab needle asukoha aadressi, kui see leitakse.

Tulemused

#include <stdio.h>
#include <string.h>

void get_domain(const char *url, char *domain) {
    char *pos = strstr(url, "://"); // Search for the position of "://"

    if (pos != NULL) {
        strcpy(domain, pos + 3); // Copy from the character after "://"
    } else {
        strcpy(domain, url); // If "://" is not found, copy the entire string
    }
}

int main() {
    char url[] = "https://www.example.com/page.html";
    char domain[50];

    get_domain(url, domain);
    printf("Domain part: %s\n", domain);

    return 0;
}

Olulised punktid

Domain part: www.example.com/page.html

7.3 strchr kasutades kindla tähe eel- ja järeltükke eraldamine

  • strstr"https://""http://""//"
  • pos + 3://

Kasutusnäide: Kasutajanime ja domeeni eraldamine e-posti aadressist

strchr kasutades saab eraldada ja hankida kindla tähe eel- ja järeltükid.

Tulemused

#include <stdio.h>
#include <string.h>

void split_email(const char *email, char *username, char *domain) {
    char *pos = strchr(email, '@'); // Search for the position of '@'

    if (pos != NULL) {
        strncpy(username, email, pos - email); // Copy the part before '@'
        username[pos - email] = '\0';          // Add null terminator
        strcpy(domain, pos + 1);               // Copy the part after '@'
    }
}

int main() {
    char email[] = "user@example.com";
    char username[50], domain[50];

    split_email(email, username, domain);
    printf("Username: %s\n", username);
    printf("Domain: %s\n", domain);

    return 0;
}

Olulised punktid

Username: user
Domain: example.com

7.4 Rakendus: Spetsiifilise atribuudi ekstraheerimine HTML-sildist

  • strchr'@'
  • strncpy'@' enne osa kopeeritakse ja lisatakse null-merk
  • strcpy'@' järele jääva osa kopeerimiseks

Kasutusnäide: <a href="URL"> kaudu URL-i hankimine

Ka HTML-siltide seest spetsiifilise atribuudi hankimiseks saab kasutada strstr.

Tulemused

#include <stdio.h>
#include <string.h>

void get_href(const char *html, char *url) {
    char *start = strstr(html, "href=\""); // Search for the position of href="
    if (start != NULL) {
        start += 6; // Move past href="
        char *end = strchr(start, '"'); // Search for the next "
        if (end != NULL) {
            strncpy(url, start, end - start);
            url[end - start] = '\0'; // Add null terminator
        }
    }
}

int main() {
    char html[] = "<a href=\"https://example.com\">Click Here</a>";
    char url[100];

    get_href(html, url);
    printf("Extracted URL: %s\n", url);

    return 0;
}

Olulised punktid

Extracted URL: https://example.com

7.5 Kokkuvõte

  • strstr"href=\\\"
  • strchr"

Järeldus

Töötlemise sisuFunktsiooni kasutamineeelis
Hangi kindla märgi ees olev osastrchr / strrchrLihtne ja kiire
Hangi kindla märgi järelstrstrSõnade otsing on võimalik
Jagage ette ja taha kindla märgi abilstrchr + strncpyKasutajanime・domeeni eraldamiseks jne sobiv
HTML-tähejoone omaduste saaminestrstr + strchrVeebiskrapingu jaoks rakendatav

8. Kokkuvõte

  • strchr ja strstr kasutades, saate hõlpsasti kindla märgi või märksõna ees- ja järelosa
  • Failitee käsitlemine, URL-i analüüs, e-posti aadressi jagamine jne, on paljudes olukordades kasulik
  • Web scraping’i nagu kõrgetasemeliste protsesside puhul ka rakendatav

8.1 Artikli ülevaade

Selles artiklis käsitlesime C-gengo (C-keele) stringide lõikamise meetodeid alates põhialustest kuni rakendusteni. Siin vaatame üle iga sektsiooni olulised punktid ja korraldame parimad meetodid kasutusjuhtude kaupa.

8.2 Parimad meetodid kasutusjuhtude kaupa

SektsioonSisuOlulised punktid
C keele stringide põhialusedC-s keeles käsitletakse stringe massiivina, ja lõppmärgend on olulineTekstide käsitlemisel
Standard library abil eraldaminestrncpystrchrstrncpynull-terminaator
Kohandatud funktsiooni abil lõikamineLoo paindlik funktsioonmallocmuutuja pikkusega alamstringi
Märgi koodi kaupa töötlemineUTF-8, Shift_JIS, EUC-JP käsitlemise viismbstowcswcstombs laiendatud märgijärjestesse konverteerimine on ohutu
Stringi jagamise meetodstrtokstrtok_rstrtokalgne string muutab
Määratud märgi ees- ja järelosa väljavõtminestrchrstrstrFailinime hankimine, URL-i analüüs, HTML-i analüüs

1. Osalise stringi lõikamine

2. Stringi jagamine

kasutuse olukordoptimaalne meetod
Soovin kindla pikkusega stringi saadastrncpy or substring()
Ma tahan teha ohutut lõigetstrncpy_s
Mitu-baiti märgid (UTF-8, Shift_JIS, EUC-JP) käsitleminembstowcs / wcstombs

3. Määratud tähe eel- ja järeltõmbamine

kasutuse stsenaariumoptimaalne meetod
Soovin lihtsalt stringi eraldadastrtok
Ma tahan teha lõime turvalist jagamiststrtok_r
Soovin jagada ilma originaalkirje muutmata.Kohandatud funktsioon(split_string()

8.3 C-gengo stringide töötlemise tähelepanekud

kasutuse olukordoptimaalne meetod
Failitee kaudu faili nime hankiminestrrchr(path, '/')
URL-ist saadakse domeeni osastrstr(url, "://")
E-posti aadressist eralda kasutajanimi ja domeenistrchr(email, '@')
HTML-tähega atribuudi väärtuste saaminestrstr(tag, "href=\"") + strchr(tag, '"')

1. Null-terminaatori '
Turvalise stringi kopeerimise näide
'
haldamise ranget järgimine

2. Puhveri ületäitumise vältimine

C-gengo stringide töötlemisel on lõppmärgi '\0' õige haldamine kõige olulisem. Eriti tuleb olla ettevaatlik, kui kasutad strncpy või strchr, lisades nullmärgi käsitsi.

3. Mitme baiti tähemärkide töötlemiseks kasuta mbstowcs

#include <stdio.h>
#include <string.h>

int main() {
    char src[] = "Hello, World!";
    char dest[6];

    strncpy(dest, src, 5);
    dest[5] = '\0'; // Add null terminator for safety

    printf("Substring: %s\n", dest);

    return 0;
}

4. Puhvri suuruse haldamine

C-gengo stringi operatsioonides tuleb hoolikalt rakendada, et vältida juurdepääsu massiivi piiridest väljapoole. Eriti on oluline kontrollida kopeeritavate baitide arvu, kui kasutad strncpy.

Turvalise stringi kopeerimise näide

#include <stdio.h>
#include <string.h>

int main() {
    char src[] = "Hello, World!";
    char dest[6];

    strncpy(dest, src, sizeof(dest) - 1);
    dest[5] = '\0'; // Explicitly add null terminator

    printf("Substring: %s\n", dest);
    return 0;
}

8.4 Edasise õppe suunas

Kui töötad UTF-8 või Shift_JIS’i nagu mitme baiti tähemärkidega, ei tööta lihtsalt strncpy või strlen õigesti.

Seetõttu soovitatakse mitme baiti tähemärkide puhul kõigepealt konverteerida mbstowcs abil laiendatud stringiks ja seejärel õigesti töödelda.

#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main() {
    setlocale(LC_ALL, ""); // Set the locale

    char text[] = "こんにちは、世界!"; // UTF-8
    wchar_t wtext[256];

    mbstowcs(wtext, text, 256); // Convert to wide-character string

    printf("Converted wide-character string: %ls\n", wtext);

    return 0;
}

Teemad sügavamaks õppimiseks

Stringi töötlemisel on oluline eelnevalt arvutada vajalik mälumaht ja vältida puhvri ületäitumist. Eriti tuleks malloc kasutades dünaamilist mälu eraldades täpselt teada saada vajaliku suurus.

8.5 Kokkuvõte

C-gengo stringide töötlemine on oluline oskus, mis parandab programmi turvalisust ja loetavust. Kui rakendad selles artiklis tutvustatud teadmisi, võimaldab järgmiste teemade õppimine veelgi keerukamat stringide töötlemist.

Teemad sügavamaks õppimiseks

  1. Regulaaravaldis (regex)
  2. Failioperatsioonid(fgets, fscanf stringi töötlemine kasutades)
  3. Mälu haldamine (dünaamiliste stringide töötlemine malloc, realloc kasutades)
  4. Andmeanalüüs (JSON-i ja XML-i analüüsi meetodid)

8.5 Kokkuvõte

  1. C keele stringid on char massiiviga hallatavad, seetõttu on tähtis käsitleda lõppmärki '\0' on tähtis
  2. Alamstringi lõikamiseks strncpy, substring(), malloc kasutatakse
  3. Tekstide jagamiseks strtok / strtok_r / kasutades ise tehtud funktsioone
  4. Kui soovite kindla märgi ees- ja järelosa hankida, kasutage strchr, strstr kasutades
  5. Kui käsitlete multibaiti märke (jaapani keelt), kasutage mbstowcs kasutage
  6. Püüa tagada ohutu stringi töötlemine ja ole tähelepanelik pumba ületamiste suhtes

Kui kasutad selle artikli sisu, saad C-gengos rakendada praktilist stringide töötlemist. Pärast põhiliste funktsioonide mõistmist võta ette oma funktsioonide ja rakenduste loomine ning kirjuta tõhusamat koodi!

年収訴求