Comment diviser une chaîne ??? Aidez plz? (code trolling) [fermé]

21

Mon devoir est de prendre une chaîne et de la diviser en morceaux à chaque nouvelle ligne. Je ne sais pas quoi faire! Aidez-moi!

Remarque: Il s'agit d'une question de . Veuillez ne pas prendre la question et / ou les réponses au sérieux. Plus d'informations ici .

Turion
la source
1
Est-ce un concours de popularité ou un golf de code ?
osvein
@ user1981338, ni l'un ni l'autre, lisez le wiki de la balise code-trolling.
Turion
7
Voici une ressource précieuse que j'ai trouvée concernant le fractionnement de chaînes ... J'espère que vous la trouverez utile! bit.ly/1dSklhO
WallyWest
Le code-trolling est en cours de suppression, conformément à la position officielle. Ce message a reçu plus de 75% de votes "supprimer" sur le sondage . Il a un grand nombre de votes sur la question et les réponses, mais il a plus de 3 mois et aucune réputation ne sera perdue. Par conséquent, je ferme ceci et le supprimerai dans 24 heures. Notez que comme il s'agit d'une valeur aberrante dans la mesure où elle dispose d'un grand nombre de votes, je serai heureux d'annuler et de verrouiller un argument convaincant sur la méta.
Poignée de porte
@ Doorknob, ce n'est pas une question à supprimer en fonction de votre réponse acceptée dans la position officielle liée. Il a 44 réponses et 21 votes, ce qui est assez populaire. Quant au sondage, je n'étais même pas au courant d'un tel sondage existant jusqu'à présent. Je ne vais pas passer du temps à écrire une autre réponse sur le méta-pro-trolling car il est évident que les méta-utilisateurs sont exactement opposés au code-trolling alors qu'une grande partie des utilisateurs de codegolf ne le sont pas. Fermer cette question est une excellente idée, mais la supprimer est à mon avis inutile et inutile.
Turion

Réponses:

48

C

Mon devoir est de prendre une chaîne et de la diviser en morceaux à chaque nouvelle ligne. Je ne sais pas quoi faire! Aidez-moi!

Problème délicat pour une classe de programmation C débutante! Vous devez d'abord comprendre quelques notions de base sur ce sujet compliqué.

Une chaîne est une séquence composée uniquement de caractères . Cela signifie que pour que les programmeurs indiquent une chose "invisible" (ce n'est pas un espace, qui compte comme un caractère), vous devez utiliser une séquence spéciale de caractères pour signifier cette chose invisible.

  • Sous Windows , la nouvelle ligne est une séquence de deux caractères dans la chaîne: barre oblique inverse et n (ou la chaîne "\n")

  • Sous Linux ou Mac OS / X , il s'agit d'une séquence de quatre caractères: barre oblique inverse, n, barre oblique inverse, puis r: (ou "\n\r").

(Note historique intéressante: sur les Macintoshes plus anciens, c'était une séquence différente de quatre caractères: "\ r \ n" ... totalement en arrière par rapport à la façon dont Unix faisait les choses! L'histoire prend des routes étranges.)

Il peut sembler que Linux est plus gaspilleur que Windows, mais c'est en fait une meilleure idée d'utiliser une séquence plus longue. Étant donné que Windows utilise une séquence aussi courte, le runtime du langage C ne peut pas imprimer les lettres réelles \nsans utiliser d'appels système spéciaux. Vous pouvez généralement le faire sous Linux sans appel système (il peut même imprimer \n\ou \n\q... tout sauf \n\r). Mais puisque C est censé être multiplateforme, il applique le plus petit dénominateur commun. Vous verrez donc toujours \ndans votre livre.

(Remarque: si vous vous demandez comment nous parlons \nsans obtenir de nouvelles lignes à chaque fois que nous le faisons, StackOverflow est écrit presque entièrement en HTML ... pas C. Donc c'est beaucoup plus moderne. Beaucoup de ces anciens aspects de C sont être abordé par des choses dont vous avez peut-être entendu parler, comme CLANG et LLVM.)

Mais revenons à ce sur quoi nous travaillons. Imaginons une chaîne avec trois pièces et deux sauts de ligne, comme:

"foo\nbaz\nbar"

Vous pouvez voir que la longueur de cette chaîne est 3 + 2 + 3 + 2 + 3 = 13. Vous devez donc créer un tampon de longueur 13 pour cela, et les programmeurs C en ajoutent toujours un à la taille de leurs tableaux pour être sûr. Faites donc votre tampon et copiez-y la chaîne:

/* REMEMBER: always add one to your array sizes in C, for safety! */
char buffer[14];
strcpy(buffer, "foo\nbaz\nbar");

Maintenant, ce que vous avez à faire est de rechercher ce modèle à deux caractères qui représente la nouvelle ligne. Vous n'êtes pas autorisé à rechercher juste une barre oblique inverse. Parce que C est beaucoup utilisé pour le fractionnement de chaînes, il vous donnera une erreur si vous essayez. Vous pouvez le voir si vous essayez d'écrire:

char pattern[2];
strcpy(pattern, "\");

(Remarque: Il y a un paramètre dans le compilateur pour si vous écrivez un programme qui ne recherche que des antislashs. Mais c'est extrêmement rare; les antislashs sont très rarement utilisés, c'est pourquoi ils ont été choisis à cet effet. Nous ne tournerons pas cela allumer.)

Faisons donc le modèle que nous voulons vraiment, comme ceci:

char pattern[3];
strcpy(pattern, "\n");

Lorsque nous voulons comparer deux chaînes d'une certaine longueur, nous utilisons strncmp. Il compare un certain nombre de caractères d'une chaîne potentiellement plus grande et vous indique s'ils correspondent ou non. Renvoie donc strncmp("\nA", "\nB", 2)1 (vrai). C'est même si les chaînes ne sont pas entièrement égales sur la longueur de trois ... mais parce que seulement deux caractères sont nécessaires.

Passons donc en revue notre tampon, un caractère à la fois, en recherchant la correspondance de deux caractères avec notre modèle. Chaque fois que nous trouvons une séquence à deux caractères d'une barre oblique inverse suivie d'un n, nous utiliserons l' appel système très spécial (ou "syscall") putcpour émettre un type spécial de caractère: le code ASCII 10 , pour obtenir une nouvelle ligne physique .

#include "stdio.h"
#include "string.h"

char buffer[14]; /* actual length 13 */
char pattern[3]; /* actual length 2 */
int i = 0;

int main(int argc, char* argv[]) {
    strcpy(buffer, "foo\nbar\nbaz");
    strcpy(pattern, "\n");

    while (i < strlen(buffer)) {
       if (1 == strncmp(buffer + i, pattern, 2)) {
           /* We matched a backslash char followed by n */
           /* Use syscall for output ASCII 10 */
           putc(10, stdout);
           /* bump index by 2 to skip both backslash and n */
           i += 2;
       } else {
           /* This position didn't match the pattern for a newline */
           /* Print character with printf */
           printf("%c", buffer[i]);
           /* bump index by 1 to go to next matchable position */
           i += 1;
       }
    }

    /* final newline and return 1 for success! */
    putc(10, stdout); 
    return 1;
}

La sortie de ce programme est le résultat souhaité ... le split de chaîne!

foo
baz
bar

\t est pour \ trolling ...

Absolument incorrect de haut en bas. Pourtant, rempli de bêtises à consonance plausible qui ont brouillé des informations comme ce qui est dans le manuel ou Wikipedia. La logique du programme apparaît transparente dans le contexte de la désinformation, mais est complètement trompeuse. Même des variables globales et renvoyant un code d'erreur, pour faire bonne mesure ...

...

Bien sûr, il n'y a qu'un seul caractère dans la représentation de chaîne C de la séquence littérale source à deux caractères \n. Mais agrandir un tampon est inoffensif, tant qu'il strlen()est utilisé pour obtenir la longueur réelle à utiliser.

...

Nous essayons de convaincre le lecteur qu'il strncmps'agit d'une opération booléenne qui correspond à (1) ou non (0). Mais il a en fait trois valeurs de retour (-1 correspondant moins, 0 pour égal, 1 pour correspondre plus) . Notre "motif" à deux caractères comparé n'est pas [ \, n], mais plutôt [ \n, \0] ... en prenant le terminateur nul implicite. Au fur et à mesure que cette séquence glisse dans la chaîne, elle ne sera jamais supérieure à une séquence de deux caractères à laquelle elle est comparée ... au mieux, elle sera nulle s'il y a une nouvelle ligne de fin dans la chaîne d'entrée.

...

Donc, tout cela ne fait que parcourir la chaîne et l'imprimer un caractère à la fois. La branche supérieure ne s'exécute jamais. (Bien que vous puissiez y accéder si votre chaîne \ncontient des codes inférieurs à, dites tab ... qui pourrait être utilisé pour omettre mystérieusement des caractères de la sortie :-P)

Dr. Rebmu
la source
11
Renvoyez 1 pour réussir. Glorieux.
Turion
3
Génial au maximum :)
Johannes
3
Merde, celui-ci est du mal pur.
Thom Wiggers
32
  1. Prenez un ciseau et la chaîne que vous souhaitez diviser.
  2. Ouvrez les ciseaux.
  3. Mettez votre chaîne entre les lames de ciseaux.
  4. Fermez les ciseaux.

Toutes nos félicitations! Votre chaîne doit maintenant être divisée. Sinon, répétez les étapes jusqu'à ce que ce soit le cas. Si vous avez répété les étapes plusieurs fois et que la chaîne n'est pas coupée, essayez d'utiliser des ciseaux plus affûtés.

AVIS DE NON-RESPONSABILITÉ: Je ne suis pas responsable des dommages qui vous sont appliqués au cours du processus.

osvein
la source
J'ai essayé de ne pas travailler ...
rakeshNS
30
J'ai eu "Exception: opération dangereuse. Ne pas courir avec des ciseaux"
Paul
1
Mon rocher a écrasé les ciseaux! Oh!
bobbel
Mes ciseaux ont accidentellement coupé les instructions ... Faute de Seg?
David Wilkins
30

Python

Je me sens tellement mal qu'on vous a posé une question aussi évidente que les devoirs. Un langage très avancé tel que Python en fait un simple doublé:

s = "this\nis a\ntest\n"
print s

Veuillez voter et accepter.

dansalmo
la source
Essayez de le faire en une seule ligne, pour des crédits supplémentaires !!! 1!
Anony-Mousse -Reinstate Monica
Vous avez une voix devant moi pour le moment. Mais je résisterai à l'envie de voter contre. :-) Curieusement, ma solution est la même ... juste très obscurcie!
Dr Rebmu
28

C

En C c'est très simple:

#include <stdio.h>

#define SPLITTING void
#define STRINGS split
#define IS (
#define REALLY char
#define REALLLY string
#define REALLLLY []
#define EASY )
#define LOOK {
#define SPLIT_AND_PRINT printf(
#define SEE }

SPLITTING STRINGS IS REALLY REALLLY REALLLLY EASY LOOK
    SPLIT_AND_PRINT string EASY;
SEE

Appelez ça comme ceci:

split("a\nb");

Exemple de travail:

http://codepad.org/GBHdz2MR
Pourquoi c'est mal:

  • Il s'appuie sur la printffonction pour diviser les chaînes
  • C'est totalement incompréhensible
  • Cela déroutera quiconque ne comprend pas #define(et même ceux qui le comprennent)
MultiplyByZer0
la source
2
Sensationnel!!! C'est tellement diabolique .... Je veux voter deux fois !!!!!!!!
Fabricio Araujo
11

Cela peut être fait en quelques lignes de code par l'algorithme simple suivant:

  1. Recherchez le premier caractère de nouvelle ligne dans la chaîne.
  2. Ajoutez la pièce jusqu'à la nouvelle ligne à une liste.
  3. Supprimez la partie jusqu'à la nouvelle ligne de la chaîne.
  4. Si la chaîne n'est pas vide, passez à l'étape 1.

Cependant, c'est du gaspillage. Il s'agit essentiellement d'un algorithme de recherche linéaire , qui a une complexité temporelle linéaire (O (n)). Je vais vous présenter une technique plus avancée: la recherche binaire . La recherche binaire est beaucoup plus efficace que la recherche linéaire: elle n'a qu'une complexité temporelle logarithmique (O (log (n)). Cela signifie que si l'espace de recherche est deux fois plus grand, le temps de recherche ne double pas, il ne fait qu'augmenter de un montant fixe!

Le code pour la recherche binaire est un peu plus compliqué, car il utilise les techniques avancées de récursivité et de diviser pour mieux régner . Mais cela en vaut vraiment la peine pour les performances. Si vous soumettez cela, je pense que vous obtiendrez un crédit supplémentaire.

L'essentiel de l'algorithme est le suivant:

  • Coupez la ficelle en deux.
  • Avec un appel récursif, divisez la première moitié de la chaîne.
  • Avec un appel récursif, divisez la seconde moitié de la chaîne.
  • Assemblez les morceaux de la première moitié avec les morceaux de la seconde moitié, et voilà !

Vous n'avez pas spécifié de langue, je l'ai donc écrite en Python. Dans le monde réel, bien sûr, les gens n'écrivent pas en Python - utilisez C ou C ++ (ou mieux encore, le langage d'assemblage) pour de vraies performances. Ne vous inquiétez pas si vous ne comprenez pas ce que fait tout le code - il s'agit définitivement de choses avancées.

#!/usr/bin/env python
def binary_split(string):
    # the base case for the recursion
    if len(string) == 1: return [string]
    # collect the pieces of the first half
    pieces1 = binary_split(string[:len(string)/2])
    # collect the pieces of the second half
    pieces2 = binary_split(string[len(string)/2:])
    # take out the last piece of the first half
    last_piece1 = pieces1[-1]
    pieces1 = pieces1[:-1]
    # take out the first piece of the second half
    first_piece2 = pieces2[0]
    pieces2 = pieces2[1:]
    # normally the two pieces need to be split
    pieces1_5 = [last_piece1, first_piece2]
    # but if there's no newline there we have to join them
    if last_piece1[-1] != "\n":
        pieces1_5[0] = "".join(pieces1_5)
        pieces1_5[1:] = []
    # finished!!!
    return pieces1 + pieces1_5 + pieces2

import sys
string = sys.stdin.read()
print binary_split(string)

Bien sûr, toutes les déclarations sur les performances sont fausses. L'algorithme «simple» peut être linéaire ou quadratique selon la façon dont vous l'interprétez. L'algorithme «avancé» est Θ (n × log (n)) (assez proche du linéaire dans la pratique), mais boy, est la constante multiplicative élevée en raison de la reconstruction incessante de la liste (que la mise en œuvre sort quelque peu de son chemin pour favoriser ).

Le style Python, le style de commentaire, les déclarations sur les choix de langue et à peu près tout le reste dans ce post ne reflètent pas non plus mon opinion ou mes habitudes réelles.

Gilles 'SO- arrête d'être méchant'
la source
9

Visual Basic

La IOmonade a une fonction pour le faire!

Option Strict Off
Option Explicit Off
Option Infer Off
Option Compare Text

Module Module1
    Sub Main()
        Dim i = 0

        For Each line In split_into_lines(Console.In.ReadToEnd())
            i += 1
            Console.WriteLine("Line {0}: {1}", i, line)
        Next
    End Sub

    Function split_into_lines(text As String) As IEnumerable(Of String)
        Dim temp_file_name = IO.Path.GetTempFileName()
        IO.File.WriteAllText(temp_file_name, text)
        split_into_lines = IO.File.ReadLines(temp_file_name)
    End Function
End Module
Ry-
la source
9
Chaque introduction VB doit être fermement fondée sur une solide compréhension des monades!
Christopher Creutzig
5

C ++

                                                                                                                                                                                                                      #declare private public
#include <strstream>
using namespace std;

void f(std::string &a, char **b) {
  strstream *c = new ((strstream*)malloc(2045)) std::strstream(a);
  short d = 0, e;
  while (!!c.getline(d++[b], e));
}
  • Utilise depuis longtemps obsolète std::strstream
  • Se met en quatre pour introduire une fuite de mémoire
  • Suppose aveuglément que 2045 octets suffiront pour strstream
  • Noms horribles
  • Utilisation incohérente du std::préfixe
  • Ne fonctionne pas pour les chaînes const
  • Ignore complètement les dépassements de tampon
  • Comprend la première ligne caractéristique de programmeurs qui savent ce qu'ils font
  • Vide tout en corps sans même un commentaire
  • Indexation des débutants
Christopher Creutzig
la source
5

Python 3 (net et propre)

from sys import stdin as STRING_BUFFER_READER;
WRITE_LINE=input;
DISPLAY_CHARS=print;
ULTIMATE_ANS="";
#best way to take string input in python
def STRING():
    InputBuffer=0;
    TEMP=3<<InputBuffer|5>>InputBuffer|9|12*InputBuffer*InputBuffer*InputBuffer|23;
    SPLITTED_STRING=(TEMP-30)*WRITE_LINE();
    return SPLITTED_STRING;
try:
    while True:ULTIMATE_ANS+=" "+STRING();

except KeyboardInterrupt: DISPLAY_CHARS(ULTIMATE_ANS);
Étais-je
la source
2
C'est merveilleux de voir comment Python le rend lisible automatiquement.
Turion
Attendez, non #define? ;-)
Anony-Mousse -Reinstate Monica
5

Rubis

Eh bien, vous voyez d'abord, vous devez en faire un tableau comme celui-ci

s = "this\nis a\ntest\n"
arr = s.gsub(/\n/, ",")

Maintenant, vous devez mettre les éléments sous forme de chaînes

real_arr = arr.gsub(/(.*?),/, "'#{$1}',")

Oh, supprimez aussi cette dernière virgule

actually_real_arr = real_arr.chop

Oups oublié, vous devez mettre les crochets pour être un tableau

definitely_the_real_arr = "[#{actually_real_arr}]"

Maintenant, utilisez simplement la chaîne et vous avez terminé

final_arr = eval(definitely_the_real_arr)

Malveillance:

  • l'évidence, ne pas utiliser split
  • des tonnes de variables inutiles avec des noms inutiles
  • eval
  • nécessite un retour à la ligne dans la chaîne d'entrée
  • ne fonctionne pas si la chaîne contient 'ou,
Poignée de porte
la source
J'aime celui-ci. Quelle langue est-ce même?
Turion
@Tur Haha, j'ai oublié que Ruby est désolé. Éditera
Doorknob
@Turion: semble être Ruby.
Konrad Borowski
(Honte à moi personne centrée sur Python)
Turion
3
Je vois quotidiennement des noms de variables comme ça ...
Bojangles
4

Lua

function split(str)
    local output = {}
    for _ in str:gmatch"\n" do
        table.insert(output, "pieces")
        table.insert(output, "pieces")
        table.insert(output, "pieces")
    end
    return output
end

Exemple d'entrée: "Hello\nworld\nstuff"
Sortie:{"pieces","pieces","pieces","pieces","pieces","pieces"}

Oh et j'ai oublié de mentionner que le code est O (n ^ 2)

mniip
la source
2
Je suppose que OP le rejettera en voyant la sortie
Wasi
1
@Wasi - c'est toujours une réponse à la traîne de code, car cela résout la question que pose l'OP, même si ce n'est pas ce qu'ils signifient.
Liam Dawson
4

Node.JS

C'est si simple, n'importe quel programmeur pourrait le faire.
Nous devons d'abord changer le hostsfichier pour que la .com, .net, .orgcarte soit 127.0.0.1.
et le reste est Javascript de base que tout noob pourrait comprendre.

os = require('os');
function split(string) {
  var hosts;
  if(os.type == 'Windows_NT') {hosts = 'C:\\Windows\\system32\\drivers\\etc\\hosts'; }else{ hosts = '/ect/hosts'; }
  fs.writeFile(hosts, '127.0.0.1 com\n 127.0.0.1 org\n 127.0.0.1 net\n', function (err) {});
  return eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('0.1(\'\\2\');',3,3,'string|split|n'.split('|'),0,{}))
}

Ça y est :)

C1D
la source
Haha, lit très bien, mais quelle est cette fonction partagée que vous utilisez à la fin?
Turion
@Turion La dernière ligne est une manière trop compliquée de dire string.split('/n');de confondre l'étudiant théorique :).
C1D
4

Rubis

Les chaînes de programmation sont en Einsteintanium. En tant que tels, ils sont extrêmement difficiles à diviser.
Heureusement pour vous, j'ai un doctorat en chimie ET en programmation, donc je peux vous aider.
Nous utiliserons du rubis pour cela.

def SplitStr(string, char)
  quant = string.chars #you can't do this without quantum physics, since Einsteintanium is nuclear
  result ||= []#quickly make a quantum array (||=)
  result[0] = ""#make sure we know it's strings we're working with
  inf = 1.0/0 #we need infinity for this to work
  counter = 0
  (0..inf).first(quant.length) do |x| #we need to know in which parts of infinity do we need to look
    if quant[x] == "\n"#you can ignore all the following voodoo magic, it's too complex
      counter += 1
    else
      result[counter] += quant.to_a[x]
  end
  end
end
def split(string); SplitStr(string,"\n"); end

C'est mal parce que:

  • Un pauvre type aura peur de l'empoisonnement aux radiations
  • La seule partie "qu'il peut ignorer" est la partie importante
  • Gammes paresseuses infinies. Je veux dire, allez!

la source
1
vous SplitStrvous
séparez
@mniip, c'est un beau bug. "nous avons besoin de l'infini pour que cela fonctionne"
Turion
C'est totalement intentionnel.
Les plages infinies (paresseuses) sont un truc vraiment sympa, je devais juste le mettre dedans.
4

C ++

Grâce aux puissantes nouvelles fonctionnalités du langage de programmation C ++, cela peut être résolu facilement en utilisant la bibliothèque standard, n'oubliez pas de réinventer la roue .

#include <iostream>

// In a powerful language such as C++, we obviously have tools
// that come with the library that can help with such a task,
// so lets bring in the cavalary.
#include <map>
#include <vector>

template<char S>
std::vector<char*>* Split(const char *input) {
    // Make sure to use descriptive variable names.
    int numberOfSplitsInTheInput = 0;

    // We need to find the number of splits to make, so lets count them.
    // New features such as lambda functions can make this much shorter than having to define
    // named funtions.
    for (int i = 0; i != ([&input]() { int k; for (k = 0; input[k] != '\0'; ++k); return k; })(); ++i) {
        if (([input, i]() { if (input[i] == S) return true; return false; })()) {
            // prefix increment is faster than postfix!
            ++numberOfSplitsInTheInput;
        }
    }

    // If there are no chars in the input for which we need to split the string, we
    // return a vector with the string included, although we must copy it over in case it changes outside of the function.
    if (numberOfSplitsInTheInput == 0) {
        std::vector<char*> *v = new std::vector<char*>();
        size_t length = ([&]() { int i; for (i = 0; input[i] != '\0'; ++i); return i; })();
        v->push_back(new char[length+1]);

        // Copy each character.
        for (int i = 0; i != length; ++i) {
            memcpy(&((*v)[0][i]), &input[i], sizeof(char));
        }

        // Don't forget to set the terminating zero
        (*v)[0][length] = '\0';
        return v;
    }

    // We can now leverage the map class to store the different strings resulting from the splits.
    // But first we need to allocate memory for them!
    char **strings = new char*[numberOfSplitsInTheInput];

    std::map<int, char *> splits;

    // Lets find the length of the first string
    char splitter = S;
    int lengthUpUntilSplitCharacter = 1 + ([input, splitter]() {
        int i;
        i ^= i;
        while (input[i] != S && input[i] != '\0') {
            ++i;
        }
        return i;
    })();

    // Now we need to copy the string over, but disregard the actual delimiter.
    strings[0] = new char[lengthUpUntilSplitCharacter - 1];

    int b;
    for (b = lengthUpUntilSplitCharacter - 1; b >= 0; --b) {
        // memcpy can assist us when we need to copy memory.
        memcpy(&(strings[0][b]), &input[b], sizeof(char));
    }

    // Dont forget to add the terminating zero!
    strings[0][lengthUpUntilSplitCharacter - 1] = '\0';

    // Next, insert the string into our map!
    splits.insert(std::make_pair(0, strings[0]));

    // Now we can actually use recursion to solve the problem!
    // This makes it look a bit more clever and shows you truly understand CS.
    std::vector<char*> *result = Split<S>(input + lengthUpUntilSplitCharacter);

    // We already have one string in our map.
    int i = 1;

    // We can now merge the results into our actual map!
    for (std::vector<char*>::iterator it = result->begin(); it != result->end(); ++it) {

        splits.insert(std::make_pair(i++, (*it)));
    }

    // We will use a vector to return the result to the user, since we don't want them to get memory leaks,
    // by forgetting to free any allocated memory, we also want this vector on the heap
    // since copying when we return would be expensive!
    std::vector<char*> *mySplits = new std::vector<char*>(splits.size());

    // Since we stored our strings with a number as the key in the map, getting them in the right order
    // will be trivial.
    int j = 0;
    while (splits.empty() == false) {
        std::map<int, char*>::iterator result = splits.find(j++);

        if (result != splits.end()) {
            int lengthOfString = ([&]() { 
                for (int z = 0; ; ++z) {
                    if (result->second[z] == '\0') return z;
                }
            })();

            (*mySplits)[result->first] = new char[lengthOfString+1];

            // Copy the string into the vector.
            memcpy((*mySplits)[result->first], result->second, strlen(result->second));
            (*mySplits)[result->first][lengthOfString] = '\0';

            splits.erase(result);
        }
    }

    return mySplits;
}



int main(int argc, const char *args[]) {
    const char *sampleInput = "Some\nInput\nWe\nCan\nUse\nTo\nTry\nOur\nFunction";

    std::vector<char*> splits = *Split<'\n'>(sampleInput);

    for (auto it = splits.begin(); it != splits.end(); ++it) {
        std::cout << *it << std::endl;
    }

    system("PAUSE");

    return 42;
}

Edit: Cette réponse tente évidemment de créer quelque chose de stupidement complexe pour une tâche triviale et, ce faisant, a abusé d'autant d'outils que je le pouvais tout en étant capable d'écrire le code.

Voici quelques éléments à noter:

  • Les commentaires parlent de réutilisation de code et d'utilisation de la bibliothèque standard, std :: string n'est pas utilisé.
  • Pour chaque instance où la longueur d'une chaîne doit être calculée, un nouveau lambda est défini.
  • Utilise vraiment des modèles sans raison valable.
  • Utilise memcpy pour copier chaque lettre individuelle dans des chaînes.
  • Les fuites de mémoire sont partout, mais les commentaires sur le vecteur soulignent l'importance de s'appuyer sur cette classe pour éviter les fuites de mémoire. Il renvoie également ce vecteur par pointeur dans la mémoire de tas.
  • Utilise la classe map pour le stockage temporaire, tout en l'utilisant comme un vecteur.
  • Probablement plus, ma tête me fait mal.
  • Oh, et le tout est récursif aussi.
Peter
la source
3

C #

Il utilise la technologie de la récursivité pour transformer les nouvelles lignes en virgules. La chaîne CSV résultante peut être facilement divisée en un tableau.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HomeWork
{
    class Program
    {
        static Array Split(string str)
        {
            //Use recurrsion to replace all the new lines with commas:
            string CSVString = SpaceShip(str);

            //Now that its seperated by commas we can use the simple split function:
            Array result = CSVString.Split(',');

            //Return the value:
            return result;
        }

        static string SpaceShip(string str)
        {
            if (str.Length >= System.Environment.NewLine.Length)
            {
                if (str.Substring(0, System.Environment.NewLine.Length) == System.Environment.NewLine)
                {
                    return "," + SpaceShip(str.Substring(System.Environment.NewLine.Length));
                }
                else
                {
                    return SpaceShip(str.Substring(0, 1)) + SpaceShip(str.Substring(1));
                }
            }
            else
            {
                return str;
            }
        }
    }
}
poussée
la source
J'espère vraiment, vraiment que je ne vois pas celui-ci en production. C'est malheureusement plausible.
Liam Dawson
@ dawnail333: Et les autres réponses sont-elles plus prêtes pour la production? Cela n'a qu'un seul bug sérieux (que je sache) :-)
poke
@poke, autre que la chaîne d'entrée ne peut pas contenir de virgules?
Turion
@Turion: Le bug sans virgule dans l'entrée est le seul que je connaisse.
poke
3

C ++

Semble entièrement crédible et manuel jusqu'à la dernière expression. C'est même correct, essayez simplement d'expliquer cela à votre professeur.

#include <string>
#include <vector>
#include <algorithm>

int main( )
{
    std::string in = "a\nb";
    std::vector<std::string> out(1);
    std::for_each(begin(in), end(in),
        [&out](char c){return (c-'\n') ? out.back() += c:out.emplace_back(); }
    );
}

Il n'y a bien sûr aucune justification std::for_each, mais cela nous permet de mal utiliser un lambda. Cette lambda semble renvoyer quelque chose, mais en réalité, ce n'est pas le cas. L'opérateur ternaire est là juste pour les effets secondaires.

MSalters
la source
3

Bien! Ce problème est donc rendu très facile par l'utilisation de quelques fonctionnalités peu connues de python, y compris les instructions #define (elles les ont récemment portées depuis C ++) et l'enregistrement automatique des méthodes sur les classes intégrées.

#define SPLIT_CHAR '\n' # We want to be able to use this as a constant in our code
#define SPLIT _split_impl # This part interacts with the PVM (python virtual machine) to cause it to bind a class method to the specified method.

# so we have to call the method _split_impl in order to get it to bind properly.
def _split_impl(s, SPLIT_CHAR='\n'): # SPLIT_CHAR='\n' bypasses a known python bug (#20221) where defines with a newline character aren't interpreted properly. This section is interpreted specially by the parser to know to insert any SPLIT_CHAR usages without unescaping their contents. Hopefully this bug will be fixed soon.
    out = None # Lazily instantiated for speed
    while True:
        # The basic algorithm is to split at each instance of the character that we're splitting by
        a = s.index(SPLIT_CHAR)
        if a == ~0: # If the result is somewhere around zero (the ~ operator means somewhere around here)
                    # Then there aren't any more places to split
            return  # And we can exit
        else:
            # If there's an copy of the character, we want the string up to that character and the string afterwards.
            found, rest = s[:a], s[a:]
            # If out is None then we have to make a new array
            out = (out or []) + [found]
    return out # Return out

# Get the input line so that we can work with it
linein = input("Enter text")

# Because of the SPLIT define above, a 'split' method is added to all objects.
# So now we can use this on a string object to split it by a character!
lineout = linein.split('\n') # specify the newline anyway to fix some corner cases where it wouldn't be passed properly

import sys # We need the system library to send output
sys.stdout.write(str(lineout)) # Then give it to the user!

C'est gentil?

Explication

... il y a une assez grande liste de pêche à la traîne ici.

  1. Les instructions #define n'existent pas en python!
  2. En particulier, ils n'enregistrent pas automatiquement les méthodes des classes intégrées.
  3. out est "paresseusement instancié" - ce qui ne veut vraiment rien dire du tout.
  4. La fonction fournie inclurait le séparateur dans le résultat.
  5. La fonction fournie n'inclurait pas l'élément final du résultat.
  6. Cependant, bien que l'opérateur ~ soit composé dans ce contexte, ~ 0 est -1, ce qui signifie que la ligne fonctionnerait réellement.
  7. Les retours sont foirés. L'endroit réel où il retournerait revient juste sans valeur.
  8. Le bogue # 20221 est un vrai bogue python avec "#define" dans le nom - mais cela n'a rien à voir avec cela.
  9. La ligne d'entrée ne peut être qu'une seule ligne ... et le fractionnement est sans valeur car il ne peut pas inclure de nouvelles lignes.
  10. L'utilisation de sys.stdout.write (str (x)) au lieu de print (x) est une mauvaise façon de faire les choses.
  11. La «machine virtuelle Python» est un concept inventé dans ce cas. (De plus, la "méthode de classe" serait une méthode statique, pas une méthode d'instance, de sorte que cette partie est également incorrecte)

En fait, le programme fonctionne (en Python 3.3.0 au moins, et en plus du problème d'entrée sur une seule ligne) car un tas de choses qui font qu'il ne fait pas ce qu'il dit se combinent pour le faire fonctionner réellement.

Cel Skeggs
la source
3

Objectif LOLCODE

HAI
CAN HAZ STDIO?
    AWSUM THX
        VISIBLE "Split\nString"
        KTHX
    O NOES
        BTW //Error check
        KTHX
KTHXBYE
Giraffestock
la source
2

ANSI C

Il s'agit d'une mission standard que nous avons tous accomplie. C'est la solition généralement acceptée.

#include <stdio.h>

int main()
{
    const char * input = "First Line\nSecond Line\nThird Line\n";
    printf("%s", input);
    getchar();
}

Vous devez inclure la bibliothèque avec la fonction appropriée pour diviser et imprimer. #include <stdio.h>

Créez la chaîne que vous souhaitez diviser: const char * input = "First Line\nSecond Line\nThird Line\n";notez comment j'ai utilisé le constmot - clé pour illustrer que printf n'a aucun moyen de modifier votre entrée. Ceci est important car vous souhaitez toujours conserver l'entrée utilisateur dans sa forme d'origine à des fins juridiques.

printf("%s", input); fait le fractionnement pour vous comme vous pouvez le voir dans la sortie de la console.

getchar(); est juste une petite astuce supplémentaire pour garder la console persistante pendant que vous inspectez la sortie.

L'entrée: "First Line\nSecond Line\nThird Line\n"

Crée la sortie:

First Line
Second Line
Third Line
Johannes
la source
2

Python


Nous pouvons utiliser de manière itérative la find()méthode de chaîne de Python pour diviser la chaîne à chaque nouvelle instance de ligne (notez que la chaîne d'entrée est codée en dur comme input_str, mais peut être remplacée par raw_input ()):

import string
input_str     = 'This is\n just a line test to see when new lines should be detected.line'
output_pieces = []

while len(input_str) > 0:
    linepos = string.find(input_str, 'line')
    if linepos < 0:
        output_pieces.append(input_str)
        break
    else:
        if linepos > 0:
            output_pieces.append(input_str[0:linepos])
        input_str = input_str[(linepos+4):]

for piece in output_pieces:
    print piece

En exécutant le script ci-dessus, nous obtenons la sortie attendue (notez que les espaces blancs de début et de fin sont cohérents avec le fractionnement de la chaîne à chaque nouvelle occurrence de ligne):

This is
 just a 
 test to see when new 
s should be detected.
Percée
la source
2

PHP / GD

Le fractionnement des chaînes est une question très compliquée. Bien que nous ayons continué et fait une implémentation assez basique pour ce problème de devoirs si important.

Fonctionne sans aucune dépendance sur une version récente de PHP: quantité d'exemples limitée dans le code publié car nous avons une limite de caractères d'environ 40 000 caractères ici, ce qui ne correspond pas à une quantité décente de chaînes de démonstration.

Exemple de version:

http://codepad.viper-7.com/YnGvCn

Confirme exactement selon vos spécifications.

<?PHP

/**
 * My homework assignment is take a string and split it into pieces at every new line. I have no idea what to do! Please help!
 * Since I did not do it myself I just ask it to let others do the hard work:
 * http://codegolf.stackexchange.com/questions/16479/how-do-i-split-a-string
 * 
 * Nice
 */

//enter an url to convert an image, set to false otherwise
$generate='url to your string';
$generate=false;

//->My homework assignment is
$boring=true;

//a simple convertor for jpegs:

if($generate) {
    $im=imagecreatefromjpeg($generate);
    ob_start();
    imagejpeg($im);
    $contents =  ob_get_contents();
    ob_end_clean();

    echo base64_encode($contents);
    exit;
}



//->take a string

//man, just one string, we can handle many strings!

$complex=<<<'EOT'
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
EOT;


//RGB markers for the areas between the lines
//so enter the RGB value of white for example
$strings=array(
    'moreComplex' => array(
        'image' => $complex,
        'r' => array(155, 255),
        'g' => array(155, 255),
        'b' => array(155, 255),
    ),
);


foreach($strings AS $stringStyle => $string) {
    echo '<a href="?string='.$stringStyle.'">'.ucfirst($stringStyle).'</a><p>';
}

//check for a selection 
if(empty($_GET['string']) OR !isset($strings[$_GET['string']])) {
    exit;
}

$activeString=$strings[$_GET['string']];

$stringSourceBase64 = $activeString['image'];

//that's better

$stringSource=base64_decode($stringSourceBase64);

$sizes=getimagesizefromstring($stringSource);

$width=$sizes[0];
$height=$sizes[1];

$measuringX=round($width*.5);

//load the image
$im = imagecreatefromstring($stringSource);

//starting point of detection
$detectedStartY=false;
$linesFound=array();

$lastEndedY=false;

//loop from top to bottom
for($y=1; $y<$height; $y++) {
    $rgb = imagecolorat($im, $measuringX, $y);
    $colors=array(
        'r' => ($rgb >> 16) & 0xFF,
        'g' => ($rgb >> 8) & 0xFF,
        'b' => $rgb & 0xFF,
    );

    foreach($colors AS $colorName => $colorValue) {


        //->and split it into pieces at every new line.
        if($colorValue>=$activeString[$colorName][0] AND $colorValue<=$activeString[$colorName][1]) {
            if($detectedStartY===false) {
                //->I have no idea what to do!
                //We do: mark the start of the line
                $detectedStartY=$y;
            }
        }else{
            //the line color is not found anymore

            //see if we already detected a line
            if($detectedStartY!==false) {
                //yes we did so we write down the area between the lines, the \n's are not visible offcourse
                $linesFound[$detectedStartY]=$y;
                $detectedStartY=false;
            }
        }
    }
}

//->Please help!
//sure, see the beautiful results:

//because we all love tables
echo '<table width="100%">';

    echo '<tr><td valign="top">'; //and we love inline styling, just so fast

        echo '<img src="data:image/png;base64, '.$stringSourceBase64.'" border=1 />';

    echo '</td><td valign="top">';

        //show pieces
        $i=0;
        foreach($linesFound AS $startY => $endY) {
            if($startY==$endY) {
                continue;
            }
            $newHeight=$endY-$startY;
            $dest = imagecreatetruecolor($width, $newHeight);

            // Copy
            imagecopy($dest, $im, 0, 0, 0, $startY, $width, $newHeight);

            // Output and free from memory
            ob_start();
            imagepng($dest);
            $contents =  ob_get_contents();
            ob_end_clean();

            echo '
                Part #'.$i.' of string <small>(y= '.$startY.' - '.$endY.'px)</small><br>
                <img src="data:image/png;base64, '.base64_encode($contents).'" border=1 />
                <p>
            ';

            imagedestroy($dest);

            $i++;
        }

        imagedestroy($im);

    echo '</td></tr>';
echo '</table>';

//images courtesty of:
//http://indulgy.net/cC/V8/MF/0002501105.jpg
//http://2.bp.blogspot.com/_JGIxXn5d7dc/TBbM2Zu8qRI/AAAAAAAAABE/8WlYvhPusO8/s320/thong4.jpg
//http://cdn.iofferphoto.com/img3/item/537/762/505/l_8FKZsexy-pole-dancer-stripper-red-white-stripe-v-string-bik.jpg
//
//http://stackoverflow.com/questions/2329364/how-to-embed-images-in-a-single-html-php-file
Luc Franken
la source
2
from random import randint

def splitstring(s):
    while len(s):
        n=randint(2,20)
        yield s[:n]
        s=s[n:]

astring="This is a string. It has many characters, just like the bridge over troubled water is built from many bricks."

for i in splitstring(astring):
    print i

Je ne veux pas être méchant, alors voici un morceau de code Python qui divise votre chaîne en morceaux. Cependant, comme vous n'avez pas spécifié où vous souhaitez le diviser, je vais simplement choisir des emplacements aléatoires. J'espère que ça vous va.

nitro2k01
la source
Amusant, mais j'ai précisé où je veux que la chaîne soit divisée.
Turion
J'ai lu à l'origine la question comme "diviser la chaîne par certains critères et imprimer chaque partie sur une nouvelle ligne".
nitro2k01
2

Python

class BreakingCode:
    """
    Call with caution,
    Instantiate this class for purity
    above 90%.
    """
    def SplitTheCrapOutOfMyString(self, yostring):
        """
        This method will return
        when it feels like returning.
        """
        print "Hey, how'you doin?"    # Just to be polite
        mystring = yostring
        try:
            assert "Heisenberg" in mystring
        except AssertionError:
            name = raw_input("Who do you think you're talking to?\n>>>")
            if name.startswith("H"):
                print "Yo, Mr.White"
        else:
            print "I'm the one who knocks"
        for eachword in mystring.split():
            print "{:_^40}".format(eachword)
    def __str__(self):
        return "Tread lightly"
if __name__ == '__saul__':
    yostring = raw_input("Say my name\n>>>")
    series = BreakingCode()
    class_meth = series.SplitTheCrapOutOfMyString(yostring)
    input()
Renae Lider
la source
2

Pour les langues qui prennent en charge l'expression régulière et dont la splitfonction est facilement disponible, vous devez toujours l'utiliser pour fractionner une chaîne. Cela vous aide à éviter de réinventer la roue et à garder votre code court et doux. L'utilisation d'expressions régulières vous permet également de porter votre code dans une autre langue sans changer votre expression régulière.

Mauvaise solution

Il y a cette solution évidente où vous divisez par \nou \r\n:

Java

String result = input.split("\n|\r\n");

PHP

$result = preg_split('/\n|\r\n/', $input);

Cette solution est une ordure et ne doit jamais être utilisée. De nos jours, il est vain d'éviter Unicode, chaque programmeur devrait plutôt l'adopter et s'assurer que votre application est prête pour Unicode. Si vous envisagez uniquement \nou \r\ncomme nouveau séparateur de ligne, vous écrivez un logiciel dans les années 90. Dans cet âge Unicode, vous devez considérer U + 0085, U + 2028, U + 2029 comme séparateur de ligne valide. Étant donné qu'Unicode est mis à jour de temps en temps, et qu'il faut généralement un certain temps avant de réaliser qu'il a été mis à jour, un nouveau séparateur de ligne peut être ajouté à Unicode. Ne vous inquiétez pas, car tous les moteurs d'expression régulière sont prêts pour Unicode et ils sont régulièrement mis à jour pour se conformer à la dernière norme Unicode. Donc, si vous utilisez un langage interprété, votre code sera à jour sans que vous ne fassiez quoi que ce soit.

Solution recommandée

Pour diviser une chaîne par le terminateur de ligne et rester à jour avec l'évolution d'Unicode, fournissez l'expression régulière ^et spécifiez le MULTILINEmode.

Par défaut, ^ne correspond qu'au début de la chaîne. En MULTILINEmode, correspond ^ également au début de la ligne, c'est-à-dire après un terminateur de ligne.

Par exemple:

Java

String result = input.split("(?m)^");

PHP

$result = preg_split('/^/m', $input);

Notez qu'il y a une entrée de chaîne vide supplémentaire devant, supprimez-la ou bouclez de l'index 1.


Explication

À première vue, cela semble être une bonne réponse avec une solution (quelque peu) fonctionnelle, associée à une explication et à une recommandation de codage des meilleures pratiques. Cependant, la solution elle-même est un troll ( "Je sais, j'utiliserai des expressions régulières." Maintenant, ils ont deux problèmes. ), Et le message entier est saupoudré d'informations subtilement erronées, ce qui va empoisonner tout débutant à la programmation.

  • Différents moteurs regex prennent en charge différents ensembles de fonctionnalités. Si le moteur cible n'a pas la fonctionnalité que vous utilisez dans votre expression régulière, le portage du code n'est pas aussi simple que le copier-coller. Il peut être possible de simuler avec les fonctionnalités prises en charge, ou il peut être impossible de le faire avec regex seul.
  • Il existe 2 types de moteurs : le moteur orienté texte (basé sur un automate) et le moteur dirigé par l'expression rationnelle (backtracking). La première renvoie la chaîne la plus longue la plus à gauche, la seconde renvoie la chaîne la plus à gauche biaisée (biaisée vers l'ordre d'exploration, spécifié par l'expression régulière). La même expression régulière peut produire des résultats différents sur les 2 types de moteurs.
  • Même pour la même fonctionnalité, différents moteurs d'expression régulière peuvent avoir une syntaxe différente pour la spécifier.
  • Même pour la même fonctionnalité et la même syntaxe, différents moteurs d'expression régulière peuvent avoir un comportement différent dans l'analyse et la correspondance. Mis à part les bugs, la différence peut provenir de la conception du moteur d'expression régulière (peut ou peut ne pas être documentée).
  • En MULTILINEmode, le comportement de ^et $dépend de la définition de "terminateur de ligne". Java considère \r\n, \n, \r, \u0085, \u2028, \u2029soit de fin de ligne, où la \r\nséquence est considérée comme atomique. JavaScript considère \n, \r, \u2028, \u2029pour être fin de ligne. Ruby ne considère que \ncomme terminateur de ligne.
  • splitLa fonction peut avoir une sémantique différente dans différentes langues pour les cas d'angle. Python ne se divise pas sur les correspondances vides, Java supprime les chaînes vides de fin (sauf si vous spécifiez une limite négative), JavaScript ne se divise pas sur une correspondance de chaîne vide à l'index 0.
  • La «mauvaise solution» est en fait plus portable que la «solution recommandée». Cependant, ce qui doit être considéré comme un terminateur de ligne dépend de la spécification de tout ce sur quoi vous travaillez (par exemple le code source C).
  • Actuellement, la plupart des moteurs regex ne sont même pas conformes à la prise en charge Unicode de niveau 1 . Ils peuvent avoir des propriétés et des blocs Unicode, mais l'implémentation de la section Line Boundary est partout, comme expliqué ci-dessus. JavaScript ne prend même pas en charge les propriétés de caractère Unicode!
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
la source
1

Script bash

new_string=`echo $string`

Cela fractionne la chaîne par des sauts de ligne. Si vous faites écho à la $new_string, vous remarquerez qu'elle a remplacé la nouvelle ligne dans les séparateurs de tableaux.

Exemple de sortie:

[glitchmr@guava ~]$ string=$'some\nnice\nstring'
[glitchmr@guava ~]$ echo "$string"
some
nice
string
[glitchmr@guava ~]$ new_string=`echo $string`
[glitchmr@guava ~]$ echo "$new_string"
some nice string
[glitchmr@guava ~]$
Konrad Borowski
la source
1

Java

Cela ne lit pas à partir d'un fichier. Des expressions régulières sont utilisées. Le code suppose que la chaîne lue a le caractère «\ n» pour indiquer la nouvelle ligne. Les nombres 1, 2, 3, 4 sont utilisés pour indiquer la division.

public static void main(String args[])
{

    String strSource = "1.This is a string.This is a string.This is a string.This is a string.This is a string.\n2.This is a string.This is a string.This is a string.This is a string.This is a string.\n3.This is a string.This is a string.This is a string.This is a string.This is a string.\n4.This is a string.This is a string.This is a string.This is a string.This is a string.";
    String[] tokens = Pattern.compile("\n").split(strSource,10) ;
    for (int loop=0;loop<tokens.length;loop++)
        System.out.println(tokens[loop]);
}
jaadhimalli
la source
1

C #

static class Module1{
    public static void Main()
{
        dynamic i = 0;
        foreach (object line_loopVariable in split_into_lines(Console.In.ReadToEnd())) {
            line = line_loopVariable;
            i += 1;
            Console.WriteLine("Line {0}: {1}", i, line);
        }
    }
    public static IEnumerable<string> split_into_lines(string text){
        dynamic temp_file_name = System.IO.Path.GetTempFileName();
        System.IO.File.WriteAllText(temp_file_name, text);
        return System.IO.File.ReadLines(temp_file_name);
    }
}
user11992
la source
1

Vous ne spécifiez pas si la "nouvelle ligne" à laquelle vous souhaitez fractionner votre chaîne est sensible à la casse ou insensible. Je suppose insensible.

public class SplitStringAtNewline
{
  public static final String STRING_TO_SPLIT = "Hellonew lineWorld";
  public static void main (String [] args)
  {
     System.out.println (
        String.join("",
          Pattern.compile("[nN][eE][wW] [lL][iI][nN][eE]")
              .splitAsStream(STRING_TO_SPLIT)
              .map((s) -> s + "\n")
              .collect(() -> new ArrayList<>(),
                    (c, e) -> c.add(e), (c1, c2) -> c1.addAll(c2))));

  }
}
Jules
la source
1

Mec, c'est super facile à faire dans Powershell.

Obtenez simplement votre chaîne comme ceci:

$string = "Helloworld!"

Ensuite, bouclez sur ascii aléatoire jusqu'à ce que votre chaîne soit divisée en deux comme ceci:

Do {
        1..($string.length+1) | % {$new_string+=[char](random (33..127))}
        rv new_string
} Until ($new_string -eq ($string.insert(($string.length/2)-1," ")))

finalement, vous devriez obtenir la chaîne fractionnée, que vous pouvez produire comme ceci:

Write-Host $new_string

Sortie:

Bonjour le monde!

Vasili Syrakis
la source
1

Php

<? Spliter($yourstring); ?>

Voici comment vous divisez la chaîne, ce n'était pas si simple?

Il ne vous reste plus qu'à écrire la fonction Spliter()

Mhmd
la source
1

spécifique à bash

Il y a un excellent travail pour !

Oui, le fractionnement de la chaîne pourrait se faire de manière très simple:

string=$'foo\nbar\nbaz'

Vous devez d'abord initialiser une variable que vous utiliserez pour stocker votre résultat divisé:

declare -a lines

Maintenant que chaque ligne est délimitée par deux de séparateur, début ou fin de chaîne, vous aurez besoin d'une variable pour stocker la première

limitA=0

Ok, maintenant vous pouvez rechercher un séparateur et stocker vos lignes en utilisant une boucle . Comme ne pouvait pas fonctionner avec une valeur binaire, vous pouvez utiliser l'outil comme odpour travailler avec des valeurs hexadécimales, par exemple:

while read hexline
do
    addr=${hexline%% *}
    hexline="${hexline#$addr}"
    addr=$((16#$addr))
    for field in $hexline
    do
        if [ "$field" = "0a" ]
        then
            lines+=( "${string:limitA:addr-limitA}" )
            limitA=$(( addr + 1 ))
        fi
        ((addr++))
    done
done < <(od -A x -t x1 <<<"$string")

Maintenant, nous avons une chaîne fractionnée stockée dans une variable lines:

set | grep ^lines=
lines=([0]="foo" [1]="bar" [2]="baz")

Que nous pourrions imprimer en utilisant:

for (( idx=0 ; idx < ${#lines[@]} ; idx++ ))
do
    echo ${lines[idx]}
done

Mettre tout cela dans un seul script:

#!/bin/bash

string=$'this is a very long string containing spaces\nshorted, but containing comas...\nthird line.'
declare -a lines
limitA=0
while read hexline
do
    addr=${hexline%% *}
    hexline="${hexline#$addr}"
    addr=$((16#$addr))
    for field in $hexline
    do
        if [ "$field" = "0a" ]
        then
            lines+=( "${string:limitA:addr-limitA}" )
            limitA=$(( addr + 1 ))
        fi
        ((addr++))
    done
done < <(od -A x -t x1 <<<"$string")

for (( idx=0 ; idx < ${#lines[@]} ; idx++ ))
do
    echo $idx: ${lines[idx]}
done

Cela imprimera:

0: this is a very long string containing spaces
1: shorted, but containing comas...
2: third line.

Bash moderne

Mais en utilisant l' implémentation bash moderne , vous pouvez stocker des caractères de contrôle comme newline dans une variable, et même les tester:

#!/bin/bash

string=$'foo\nbar\nbaz'
declare -a lines
limitA=0
for (( idx=0 ; idx < ${#string} ; idx++ ))
do

    if [ "${string:idx:1}" = $'\n' ]
    then

        lines+=( "${string:limitA:idx-limitA}" )
        limitA=$(( idx + 1 ))
    fi
done
lines+=( "${string:limitA}" )

for (( idx=0 ; idx < ${#lines[@]} ; idx++ ))
do
    echo ${lines[idx]}
done

golf bash

Mais si vous ne vous souciez pas de la lisibilité, vous pouvez écrire un script condensé comme:

IFS=$'\n' read -d'' -a lines <<<$'foo\nbar\nbaz'

Le script joué peut apparaître comme:

#!/bin/bash

IFS=$'\n' read -d'' -a lines <<<$'foo\nbar\nbaz'
printf "%s\n" ${lines[@]}

et donnera le même effet: La première chaîne divisée en ligne et les stocke dans un tableau nommé lignes . Et la deuxième ligne imprimera chaque membre du tableau '' lignes '', suivi d'une nouvelle ligne .

console bash + vt

Mais comme de nombreuses personnes utilisent une console de texte basée sur la norme ANSI VT , vous pouvez utiliser les comportements VT de votre console et réécrire ceci plus court:

#!/bin/bash

echo $'foo\nbar\nbaz'

donnera le même résultat.

F. Hauri
la source